Merge branch 'master' into pu
A bit of an ugly -Xours merge in xz-utils/README.Debian.
* master:
debian: prepare for upload
xz-utils/README.Debian: flesh out "differences from upstream"
xz-utils/README.Debian: Document patches
diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644
index 0c33f15..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,7 +0,0 @@
-See the commit log in the git repository:
-
- git clone http://git.tukaani.org/xz.git
-
-Note that "make dist" doesn't put this tiny file into the package.
-Instead, the git commit log is used as ChangeLog. See dist-hook in
-Makefile.am for details.
diff --git a/INSTALL b/INSTALL
index 8b39319..c42a968 100644
--- a/INSTALL
+++ b/INSTALL
@@ -318,6 +318,11 @@
single-threaded applications and want to avoid dependency
on libpthread.
+ --enable-symbol-versions
+ Use symbol versioning for liblzma. This is enabled by
+ default on GNU/Linux, other GNU-based systems, and
+ FreeBSD.
+
--enable-debug
This enables the assert() macro and possibly some other
run-time consistency checks. It makes the code slower, so
diff --git a/NEWS b/NEWS
index 2986b51..4d4973d 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,47 @@
XZ Utils Release Notes
======================
+5.1.2alpha (2012-07-04)
+
+ * All fixes from 5.0.3 and 5.0.4
+
+ * liblzma:
+
+ - Fixed a deadlock and an invalid free() in the threaded encoder.
+
+ - Added support for symbol versioning. It is enabled by default
+ on GNU/Linux, other GNU-based systems, and FreeBSD.
+
+ - Use SHA-256 implementation from the operating system if one is
+ available in libc, libmd, or libutil. liblzma won't use e.g.
+ OpenSSL or libgcrypt to avoid introducing new dependencies.
+
+ - Fixed liblzma.pc for static linking.
+
+ - Fixed a few portability bugs.
+
+ * xz --decompress --single-stream now fixes the input position after
+ successful decompression. Now the following works:
+
+ echo foo | xz > foo.xz
+ echo bar | xz >> foo.xz
+ ( xz -dc --single-stream ; xz -dc --single-stream ) < foo.xz
+
+ Note that it doesn't work if the input is not seekable
+ or if there is Stream Padding between the concatenated
+ .xz Streams.
+
+ * xz -lvv now shows the minimum xz version that is required to
+ decompress the file. Currently it is 5.0.0 for all supported .xz
+ files except files with empty LZMA2 streams require 5.0.2.
+
+ * Added an *incomplete* implementation of --block-list=SIZES to xz.
+ It only works correctly in single-threaded mode and when
+ --block-size isn't used at the same time. --block-list allows
+ specifying the sizes of Blocks which can be useful e.g. when
+ creating files for random-access reading.
+
+
5.1.1alpha (2011-04-12)
* All fixes from 5.0.2
@@ -45,6 +86,43 @@
experimental and may change before it gets into a stable release.
+5.0.4 (2012-06-22)
+
+ * liblzma:
+
+ - Fix lzma_index_init(). It could crash if memory allocation
+ failed.
+
+ - Fix the possibility of an incorrect LZMA_BUF_ERROR when a BCJ
+ filter is used and the application only provides exactly as
+ much output space as is the uncompressed size of the file.
+
+ - Fix a bug in doc/examples_old/xz_pipe_decompress.c. It didn't
+ check if the last call to lzma_code() really returned
+ LZMA_STREAM_END, which made the program think that truncated
+ files are valid.
+
+ - New example programs in doc/examples (old programs are now in
+ doc/examples_old). These have more comments and more detailed
+ error handling.
+
+ * Fix "xz -lvv foo.xz". It could crash on some corrupted files.
+
+ * Fix output of "xz --robot -lv" and "xz --robot -lvv" which
+ incorrectly printed the filename also in the "foo (x/x)" format.
+
+ * Fix exit status of "xzdiff foo.xz bar.xz".
+
+ * Fix exit status of "xzgrep foo binary_file".
+
+ * Fix portability to EBCDIC systems.
+
+ * Fix a configure issue on AIX with the XL C compiler. See INSTALL
+ for details.
+
+ * Update French, German, Italian, and Polish translations.
+
+
5.0.3 (2011-05-21)
* liblzma fixes:
diff --git a/TODO b/TODO
index 9448660..9cdb419 100644
--- a/TODO
+++ b/TODO
@@ -32,10 +32,20 @@
time and calculated (de)compression speed won't make sense in the
progress indicator (xz --verbose).
+ If liblzma has created threads and fork() gets called, liblzma
+ code will break in the child process unless it calls exec() and
+ doesn't touch liblzma.
+
Missing features
----------------
+ Support LZMA_FINISH in raw decoder to indicate end of LZMA1 and
+ other streams that don't have an end of payload marker.
+
+ Adjust dictionary size when the input file size is known.
+ Maybe do this only if an option is given.
+
xz doesn't support copying extended attributes, access control
lists etc. from source to target file.
@@ -53,8 +63,6 @@
It will be a separate library that supports uncompressed, .gz,
.bz2, .lzma, and .xz files.
- Check the first 0x00 byte of LZMA data.
-
Support changing lzma_options_lzma.mode with lzma_filters_update().
Support LZMA_FULL_FLUSH for lzma_stream_decoder() to stop at
diff --git a/configure.ac b/configure.ac
index 0c2f2fc..bfc3ed7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -414,6 +414,10 @@
[], [enable_symbol_versions=auto])
if test "x$enable_symbol_versions" = xauto; then
case $host_os in
+ # NOTE: Even if one omits -gnu on GNU/Linux (e.g.
+ # i486-slackware-linux), configure will (via config.sub)
+ # append -gnu (e.g. i486-slackware-linux-gnu), and this
+ # test will work correctly.
gnu* | *-gnu* | freebsd*)
enable_symbol_versions=yes
;;
@@ -451,6 +455,8 @@
AM_PROG_AS
AC_USE_SYSTEM_EXTENSIONS
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
+
if test "x$enable_threads" = xyes; then
echo
echo "Threading support:"
@@ -471,6 +477,7 @@
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
CFLAGS=$OLD_CFLAGS
fi
+AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
# As a Debian-specific hack, liblzma can use dlopen() to check if extra
# paranoia is needed because unversioned symbols from liblzma.so.2 are
diff --git a/debian/changelog b/debian/changelog
index fb4eeb7..54f0aa5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,32 @@
+xz-utils (5.1.2alpha-exp0.1) experimental; urgency=low
+
+ * Multithreaded compression support.
+ "xz --threads" and the lzma_stream_encoder_mt() function use
+ multiple threads to compress. This is an experimental feature
+ and the interface is subject to change.
+ * xz-utils: Update package description to reflect threading
+ support.
+ * debian/symbols: XZ_5.1.2alpha symbols require the experimental
+ version of liblzma. Interfaces and functionality may change
+ from snapshot to snapshot.
+ * xz: Re-enable the --block-list option.
+ * debian/rules: Replace output of gcc command lines with briefer,
+ kbuild-style "CC target.lo" context lines when DEB_BUILD_OPTIONS
+ contains "quiet".
+
+ -- Jonathan Nieder <jrnieder@gmail.com> Mon, 28 May 2012 20:46:41 -0500
+
+xz-utils (5.1.2alpha-0.1) experimental; urgency=low
+
+ * New upstream alpha release.
+ * Remove support for the new --block-list option to give the
+ interface time to evolve.
+ * debian/rules clean: Remove more files not included in the
+ release tarball.
+ * Lower priority of xz-utils to standard. Closes: #685203.
+
+ -- Jonathan Nieder <jrnieder@gmail.com> Wed, 04 Jul 2012 16:18:33 -0500
+
xz-utils (5.1.1alpha+20120614-2) unstable; urgency=low
* Apply fixes from 5.1.2alpha. Closes: #685220.
diff --git a/debian/clean.sh b/debian/clean.sh
index 1a2f8b3..f172f81 100644
--- a/debian/clean.sh
+++ b/debian/clean.sh
@@ -38,6 +38,7 @@
'
dh_testdir
+rm -f macosx/build.sh src/liblzma/validate_map.sh
rm -f debug/translation.bash tests/test_block.c ChangeLog
rm -f ABOUT-NLS aclocal.m4 config.h.in configure
(cd po && perl -e "$remove_files") < debian/generated-po.list
diff --git a/debian/control b/debian/control
index 986f0c1..d3b501b 100644
--- a/debian/control
+++ b/debian/control
@@ -29,6 +29,7 @@
format, use the p7zip package instead.)
Package: xz-utils
+Priority: standard
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Multi-Arch: foreign
@@ -53,7 +54,7 @@
* 'file' magic for detecting XZ files;
* crc64 data integrity check;
* limited random-access reading support;
- * improved support for multithreading (not used in xz-utils);
+ * improved support for multithreading;
* support for flushing the encoder.
Package: xzdec
diff --git a/debian/patches/abi-liblzma2-compat b/debian/patches/abi-liblzma2-compat
index 051ab5c..cb29d3e 100644
--- a/debian/patches/abi-liblzma2-compat
+++ b/debian/patches/abi-liblzma2-compat
@@ -95,23 +95,23 @@
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
-index 25eb838f..88b81ba1 100644
+index f18f8959..1476c8e2 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -471,6 +471,11 @@ if test "x$enable_threads" = xyes; then
- AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
- CFLAGS=$OLD_CFLAGS
+@@ -479,6 +479,11 @@ if test "x$enable_threads" = xyes; then
fi
-+
+ AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
+
+# As a Debian-specific hack, liblzma uses dlopen() to check if extra
+# paranoia is needed because unversioned symbols from liblzma.so.2 are
+# present in the same process. See src/liblzma/common/common.c.
+AC_SEARCH_LIBS([dlopen], [dl])
-
++
echo
echo "Initializing Libtool:"
+ LT_PREREQ([2.2])
diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index 50c984c7..e61d940d 100644
+index 85ae96a9..f1693a01 100644
--- a/src/liblzma/common/common.c
+++ b/src/liblzma/common/common.c
@@ -12,6 +12,8 @@
@@ -190,10 +190,10 @@
|| strm->reserved_int3 != 0
|| strm->reserved_int4 != 0
diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 45aba4f0..475661d8 100644
+index 5c92af27..de482b38 100644
--- a/src/liblzma/common/common.h
+++ b/src/liblzma/common/common.h
-@@ -200,6 +200,10 @@ struct lzma_internal_s {
+@@ -216,6 +216,10 @@ struct lzma_internal_s {
/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
/// made (no input consumed and no output produced by next.code).
bool allow_buf_error;
diff --git a/debian/patches/abi-threaded-encoder b/debian/patches/abi-threaded-encoder
deleted file mode 100644
index 04babbf..0000000
--- a/debian/patches/abi-threaded-encoder
+++ /dev/null
@@ -1,2163 +0,0 @@
-From: Jonathan Nieder <jrnieder@gmail.com>
-Date: Sat, 11 Jun 2011 21:41:15 -0500
-Subject: Remove threading functionality for now
-
-This reverts the following commits:
-
- - 6ef4eabc0 (Bump the version number to 5.1.1alpha and liblzma soname
- to 5.0.99)
- - 70e750f59 (xz: Update the man page about threading)
- - c29e6630c (xz: Print the maximum number of worker threads in xz -vv)
- - 335fe260a (xz: Minor internal changes to handling of --threads)
- - 24e0406c0 (xz: Add support for threaded compression)
- - 9a4377be0 (Put the unstable APIs behind #ifdef LZMA_UNSTABLE)
- - de678e0c9 (liblmza: Add lzma_stream_encoder_mt() for threaded
- compression)
-
-The multithreaded compression functions, while useful, are not set in
-stone as part of the stable ABI. Changes will be easier to weather
-until the functions stabilize if they are left out from the
-non-experimental development branch of Debian for now.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- configure.ac | 1 -
- src/liblzma/Makefile.am | 2 +-
- src/liblzma/api/lzma/container.h | 167 ------
- src/liblzma/api/lzma/version.h | 2 +-
- src/liblzma/common/Makefile.inc | 7 -
- src/liblzma/common/common.c | 9 +-
- src/liblzma/common/common.h | 16 -
- src/liblzma/common/outqueue.c | 184 ------
- src/liblzma/common/outqueue.h | 155 -----
- src/liblzma/common/stream_encoder_mt.c | 1013 --------------------------------
- src/xz/args.c | 5 +-
- src/xz/coder.c | 210 +++----
- src/xz/hardware.c | 24 +-
- src/xz/hardware.h | 9 +-
- src/xz/private.h | 2 -
- src/xz/xz.1 | 34 +-
- 16 files changed, 117 insertions(+), 1723 deletions(-)
- delete mode 100644 src/liblzma/common/outqueue.c
- delete mode 100644 src/liblzma/common/outqueue.h
- delete mode 100644 src/liblzma/common/stream_encoder_mt.c
-
-diff --git a/configure.ac b/configure.ac
-index 25eb838..c9585e5 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -471,7 +471,6 @@ if test "x$enable_threads" = xyes; then
- AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
- CFLAGS=$OLD_CFLAGS
- fi
--AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
-
- echo
- echo "Initializing Libtool:"
-diff --git a/src/liblzma/Makefile.am b/src/liblzma/Makefile.am
-index 5bd205d..ac2d1ed 100644
---- a/src/liblzma/Makefile.am
-+++ b/src/liblzma/Makefile.am
-@@ -24,7 +24,7 @@ liblzma_la_CPPFLAGS = \
- -I$(top_srcdir)/src/liblzma/simple \
- -I$(top_srcdir)/src/common \
- -DTUKLIB_SYMBOL_PREFIX=lzma_
--liblzma_la_LDFLAGS = -no-undefined -version-info 5:99:0
-+liblzma_la_LDFLAGS = -no-undefined -version-info 5:0:0
-
- if COND_SYMVERS
- EXTRA_DIST += liblzma.map
-diff --git a/src/liblzma/api/lzma/container.h b/src/liblzma/api/lzma/container.h
-index 499d8b9..7a9ffc6 100644
---- a/src/liblzma/api/lzma/container.h
-+++ b/src/liblzma/api/lzma/container.h
-@@ -60,129 +60,6 @@
- #define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
-
-
--#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
--/**
-- * \brief Multithreading options
-- */
--typedef struct {
-- /**
-- * \brief Flags
-- *
-- * Set this to zero if no flags are wanted.
-- *
-- * No flags are currently supported.
-- */
-- uint32_t flags;
--
-- /**
-- * \brief Number of worker threads to use
-- */
-- uint32_t threads;
--
-- /**
-- * \brief Maximum uncompressed size of a Block
-- *
-- * The encoder will start a new .xz Block every block_size bytes.
-- * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()
-- * the caller may tell liblzma to start a new Block earlier.
-- *
-- * With LZMA2, a recommended block size is 2-4 times the LZMA2
-- * dictionary size. With very small dictionaries, it is recommended
-- * to use at least 1 MiB block size for good compression ratio, even
-- * if this is more than four times the dictionary size. Note that
-- * these are only recommendations for typical use cases; feel free
-- * to use other values. Just keep in mind that using a block size
-- * less than the LZMA2 dictionary size is waste of RAM.
-- *
-- * Set this to 0 to let liblzma choose the block size depending
-- * on the compression options. For LZMA2 it will be 3*dict_size
-- * or 1 MiB, whichever is more.
-- */
-- uint64_t block_size;
--
-- /**
-- * \brief Timeout to allow lzma_code() to return early
-- *
-- * Multithreading can make liblzma to consume input and produce
-- * output in a very bursty way: it may first read a lot of input
-- * to fill internal buffers, then no input or output occurs for
-- * a while.
-- *
-- * In single-threaded mode, lzma_code() won't return until it has
-- * either consumed all the input or filled the output buffer. If
-- * this is done in multithreaded mode, it may cause a call
-- * lzma_code() to take even tens of seconds, which isn't acceptable
-- * in all applications.
-- *
-- * To avoid very long blocking times in lzma_code(), a timeout
-- * (in milliseconds) may be set here. If lzma_code() would block
-- * longer than this number of milliseconds, it will return with
-- * LZMA_OK. Reasonable values are 100 ms or more. The xz command
-- * line tool uses 300 ms.
-- *
-- * If long blocking times are fine for you, set timeout to a special
-- * value of 0, which will disable the timeout mechanism and will make
-- * lzma_code() block until all the input is consumed or the output
-- * buffer has been filled.
-- *
-- * \note Even with a timeout, lzma_code() might sometimes take
-- * somewhat long time to return. No timing guarantees
-- * are made.
-- */
-- uint32_t timeout;
--
-- /**
-- * \brief Compression preset (level and possible flags)
-- *
-- * The preset is set just like with lzma_easy_encoder().
-- * The preset is ignored if filters below is non-NULL.
-- */
-- uint32_t preset;
--
-- /**
-- * \brief Filter chain (alternative to a preset)
-- *
-- * If this is NULL, the preset above is used. Otherwise the preset
-- * is ignored and the filter chain specified here is used.
-- */
-- const lzma_filter *filters;
--
-- /**
-- * \brief Integrity check type
-- *
-- * See check.h for available checks. The xz command line tool
-- * defaults to LZMA_CHECK_CRC64, which is a good choice if you
-- * are unsure.
-- */
-- lzma_check check;
--
-- /*
-- * Reserved space to allow possible future extensions without
-- * breaking the ABI. You should not touch these, because the names
-- * of these variables may change. These are and will never be used
-- * with the currently supported options, so it is safe to leave these
-- * uninitialized.
-- */
-- lzma_reserved_enum reserved_enum1;
-- lzma_reserved_enum reserved_enum2;
-- lzma_reserved_enum reserved_enum3;
-- uint32_t reserved_int1;
-- uint32_t reserved_int2;
-- uint32_t reserved_int3;
-- uint32_t reserved_int4;
-- uint64_t reserved_int5;
-- uint64_t reserved_int6;
-- uint64_t reserved_int7;
-- uint64_t reserved_int8;
-- void *reserved_ptr1;
-- void *reserved_ptr2;
-- void *reserved_ptr3;
-- void *reserved_ptr4;
--
--} lzma_mt;
--#endif
--
--
- /**
- * \brief Calculate approximate memory usage of easy encoder
- *
-@@ -313,50 +190,6 @@ extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
- lzma_nothrow lzma_attr_warn_unused_result;
-
-
--#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
--/**
-- * \brief Calculate approximate memory usage of multithreaded .xz encoder
-- *
-- * Since doing the encoding in threaded mode doesn't affect the memory
-- * requirements of single-threaded decompressor, you can use
-- * lzma_easy_decoder_memusage(options->preset) or
-- * lzma_raw_decoder_memusage(options->filters) to calculate
-- * the decompressor memory requirements.
-- *
-- * \param options Compression options
-- *
-- * \return Number of bytes of memory required for encoding with the
-- * given options. If an error occurs, for example due to
-- * unsupported preset or filter chain, UINT64_MAX is returned.
-- */
--extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
-- const lzma_mt *options) lzma_nothrow lzma_attr_pure;
--
--
--/**
-- * \brief Initialize multithreaded .xz Stream encoder
-- *
-- * This provides the functionality of lzma_easy_encoder() and
-- * lzma_stream_encoder() as a single function for multithreaded use.
-- *
-- * TODO: For lzma_code(), only LZMA_RUN and LZMA_FINISH are currently
-- * supported. Support for other actions has been planned.
-- *
-- * \param strm Pointer to properly prepared lzma_stream
-- * \param options Pointer to multithreaded compression options
-- *
-- * \return - LZMA_OK
-- * - LZMA_MEM_ERROR
-- * - LZMA_UNSUPPORTED_CHECK
-- * - LZMA_OPTIONS_ERROR
-- * - LZMA_PROG_ERROR
-- */
--extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
-- lzma_stream *strm, const lzma_mt *options)
-- lzma_nothrow lzma_attr_warn_unused_result;
--#endif
--
--
- /**
- * \brief Initialize .lzma encoder (legacy file format)
- *
-diff --git a/src/liblzma/api/lzma/version.h b/src/liblzma/api/lzma/version.h
-index 4bf7e40..a908ea2 100644
---- a/src/liblzma/api/lzma/version.h
-+++ b/src/liblzma/api/lzma/version.h
-@@ -22,7 +22,7 @@
- */
- #define LZMA_VERSION_MAJOR 5
- #define LZMA_VERSION_MINOR 1
--#define LZMA_VERSION_PATCH 1
-+#define LZMA_VERSION_PATCH 0
- #define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
-
- #ifndef LZMA_VERSION_COMMIT
-diff --git a/src/liblzma/common/Makefile.inc b/src/liblzma/common/Makefile.inc
-index dd5a8c8..81d751e 100644
---- a/src/liblzma/common/Makefile.inc
-+++ b/src/liblzma/common/Makefile.inc
-@@ -40,13 +40,6 @@ liblzma_la_SOURCES += \
- common/stream_encoder.c \
- common/stream_flags_encoder.c \
- common/vli_encoder.c
--
--if COND_THREADS
--liblzma_la_SOURCES += \
-- common/outqueue.c \
-- common/outqueue.h \
-- common/stream_encoder_mt.c
--endif
- endif
-
- if COND_MAIN_DECODER
-diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index 85ae96a..50c984c 100644
---- a/src/liblzma/common/common.c
-+++ b/src/liblzma/common/common.c
-@@ -263,9 +263,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
-
- strm->internal->avail_in = strm->avail_in;
-
-- // Cast is needed to silence a warning about LZMA_TIMED_OUT, which
-- // isn't part of lzma_ret enumeration.
-- switch ((unsigned int)(ret)) {
-+ switch (ret) {
- case LZMA_OK:
- // Don't return LZMA_BUF_ERROR when it happens the first time.
- // This is to avoid returning LZMA_BUF_ERROR when avail_out
-@@ -281,11 +279,6 @@ lzma_code(lzma_stream *strm, lzma_action action)
- }
- break;
-
-- case LZMA_TIMED_OUT:
-- strm->internal->allow_buf_error = false;
-- ret = LZMA_OK;
-- break;
--
- case LZMA_STREAM_END:
- if (strm->internal->sequence == ISEQ_SYNC_FLUSH
- || strm->internal->sequence == ISEQ_FULL_FLUSH)
-diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 5c92af2..45aba4f 100644
---- a/src/liblzma/common/common.h
-+++ b/src/liblzma/common/common.h
-@@ -32,8 +32,6 @@
-
- #define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
-
--#define LZMA_UNSTABLE
--
- #include "lzma.h"
-
- // These allow helping the compiler in some often-executed branches, whose
-@@ -51,13 +49,6 @@
- #define LZMA_BUFFER_SIZE 4096
-
-
--/// Maximum number of worker threads within one multithreaded component.
--/// The limit exists solely to make it simpler to prevent integer overflows
--/// when allocating structures etc. This should be big enough for now...
--/// the code won't scale anywhere close to this number anyway.
--#define LZMA_THREADS_MAX 16384
--
--
- /// Starting value for memory usage estimates. Instead of calculating size
- /// of _every_ structure and taking into account malloc() overhead etc., we
- /// add a base size to all memory usage estimates. It's not very accurate
-@@ -78,13 +69,6 @@
- | LZMA_CONCATENATED )
-
-
--/// Special return value (lzma_ret) to indicate that a timeout was reached
--/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
--/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
--/// there's no need to have it in the public API.
--#define LZMA_TIMED_OUT 32
--
--
- /// Type of encoder/decoder specific data; the actual structure is defined
- /// differently in different coders.
- typedef struct lzma_coder_s lzma_coder;
-diff --git a/src/liblzma/common/outqueue.c b/src/liblzma/common/outqueue.c
-deleted file mode 100644
-index d7a87d9..0000000
---- a/src/liblzma/common/outqueue.c
-+++ /dev/null
-@@ -1,184 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file outqueue.c
--/// \brief Output queue handling in multithreaded coding
--//
--// Author: Lasse Collin
--//
--// This file has been put into the public domain.
--// You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "outqueue.h"
--
--
--/// This is to ease integer overflow checking: We may allocate up to
--/// 2 * LZMA_THREADS_MAX buffers and we need some extra memory for other
--/// data structures (that's the second /2).
--#define BUF_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX / 2 / 2)
--
--
--static lzma_ret
--get_options(uint64_t *bufs_alloc_size, uint32_t *bufs_count,
-- uint64_t buf_size_max, uint32_t threads)
--{
-- if (threads > LZMA_THREADS_MAX || buf_size_max > BUF_SIZE_MAX)
-- return LZMA_OPTIONS_ERROR;
--
-- // The number of buffers is twice the number of threads.
-- // This wastes RAM but keeps the threads busy when buffers
-- // finish out of order.
-- //
-- // NOTE: If this is changed, update BUF_SIZE_MAX too.
-- *bufs_count = threads * 2;
-- *bufs_alloc_size = *bufs_count * buf_size_max;
--
-- return LZMA_OK;
--}
--
--
--extern uint64_t
--lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
--{
-- uint64_t bufs_alloc_size;
-- uint32_t bufs_count;
--
-- if (get_options(&bufs_alloc_size, &bufs_count, buf_size_max, threads)
-- != LZMA_OK)
-- return UINT64_MAX;
--
-- return sizeof(lzma_outq) + bufs_count * sizeof(lzma_outbuf)
-- + bufs_alloc_size;
--}
--
--
--extern lzma_ret
--lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
-- uint64_t buf_size_max, uint32_t threads)
--{
-- uint64_t bufs_alloc_size;
-- uint32_t bufs_count;
--
-- // Set bufs_count and bufs_alloc_size.
-- return_if_error(get_options(&bufs_alloc_size, &bufs_count,
-- buf_size_max, threads));
--
-- // Allocate memory if needed.
-- if (outq->buf_size_max != buf_size_max
-- || outq->bufs_allocated != bufs_count) {
-- lzma_outq_end(outq, allocator);
--
--#if SIZE_MAX < UINT64_MAX
-- if (bufs_alloc_size > SIZE_MAX)
-- return LZMA_MEM_ERROR;
--#endif
--
-- outq->bufs = lzma_alloc(bufs_count * sizeof(lzma_outbuf),
-- allocator);
-- outq->bufs_mem = lzma_alloc((size_t)(bufs_alloc_size),
-- allocator);
--
-- if (outq->bufs == NULL || outq->bufs_mem == NULL) {
-- lzma_outq_end(outq, allocator);
-- return LZMA_MEM_ERROR;
-- }
-- }
--
-- // Initialize the rest of the main structure. Initialization of
-- // outq->bufs[] is done when they are actually needed.
-- outq->buf_size_max = (size_t)(buf_size_max);
-- outq->bufs_allocated = bufs_count;
-- outq->bufs_pos = 0;
-- outq->bufs_used = 0;
-- outq->read_pos = 0;
--
-- return LZMA_OK;
--}
--
--
--extern void
--lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator)
--{
-- lzma_free(outq->bufs, allocator);
-- outq->bufs = NULL;
--
-- lzma_free(outq->bufs_mem, allocator);
-- outq->bufs_mem = NULL;
--
-- return;
--}
--
--
--extern lzma_outbuf *
--lzma_outq_get_buf(lzma_outq *outq)
--{
-- // Caller must have checked it with lzma_outq_has_buf().
-- assert(outq->bufs_used < outq->bufs_allocated);
--
-- // Initialize the new buffer.
-- lzma_outbuf *buf = &outq->bufs[outq->bufs_pos];
-- buf->buf = outq->bufs_mem + outq->bufs_pos * outq->buf_size_max;
-- buf->size = 0;
-- buf->finished = false;
--
-- // Update the queue state.
-- if (++outq->bufs_pos == outq->bufs_allocated)
-- outq->bufs_pos = 0;
--
-- ++outq->bufs_used;
--
-- return buf;
--}
--
--
--extern bool
--lzma_outq_is_readable(const lzma_outq *outq)
--{
-- uint32_t i = outq->bufs_pos - outq->bufs_used;
-- if (outq->bufs_pos < outq->bufs_used)
-- i += outq->bufs_allocated;
--
-- return outq->bufs[i].finished;
--}
--
--
--extern lzma_ret
--lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out,
-- size_t *restrict out_pos, size_t out_size,
-- lzma_vli *restrict unpadded_size,
-- lzma_vli *restrict uncompressed_size)
--{
-- // There must be at least one buffer from which to read.
-- if (outq->bufs_used == 0)
-- return LZMA_OK;
--
-- // Get the buffer.
-- uint32_t i = outq->bufs_pos - outq->bufs_used;
-- if (outq->bufs_pos < outq->bufs_used)
-- i += outq->bufs_allocated;
--
-- lzma_outbuf *buf = &outq->bufs[i];
--
-- // If it isn't finished yet, we cannot read from it.
-- if (!buf->finished)
-- return LZMA_OK;
--
-- // Copy from the buffer to output.
-- lzma_bufcpy(buf->buf, &outq->read_pos, buf->size,
-- out, out_pos, out_size);
--
-- // Return if we didn't get all the data from the buffer.
-- if (outq->read_pos < buf->size)
-- return LZMA_OK;
--
-- // The buffer was finished. Tell the caller its size information.
-- *unpadded_size = buf->unpadded_size;
-- *uncompressed_size = buf->uncompressed_size;
--
-- // Free this buffer for further use.
-- --outq->bufs_used;
-- outq->read_pos = 0;
--
-- return LZMA_STREAM_END;
--}
-diff --git a/src/liblzma/common/outqueue.h b/src/liblzma/common/outqueue.h
-deleted file mode 100644
-index 154f91b..0000000
---- a/src/liblzma/common/outqueue.h
-+++ /dev/null
-@@ -1,155 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file outqueue.h
--/// \brief Output queue handling in multithreaded coding
--//
--// Author: Lasse Collin
--//
--// This file has been put into the public domain.
--// You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "common.h"
--
--
--/// Output buffer for a single thread
--typedef struct {
-- /// Pointer to the output buffer of lzma_outq.buf_size_max bytes
-- uint8_t *buf;
--
-- /// Amount of data written to buf
-- size_t size;
--
-- /// Additional size information
-- lzma_vli unpadded_size;
-- lzma_vli uncompressed_size;
--
-- /// True when no more data will be written into this buffer.
-- ///
-- /// \note This is read by another thread and thus access
-- /// to this variable needs a mutex.
-- bool finished;
--
--} lzma_outbuf;
--
--
--typedef struct {
-- /// Array of buffers that are used cyclically.
-- lzma_outbuf *bufs;
--
-- /// Memory allocated for all the buffers
-- uint8_t *bufs_mem;
--
-- /// Amount of buffer space available in each buffer
-- size_t buf_size_max;
--
-- /// Number of buffers allocated
-- uint32_t bufs_allocated;
--
-- /// Position in the bufs array. The next buffer to be taken
-- /// into use is bufs[bufs_pos].
-- uint32_t bufs_pos;
--
-- /// Number of buffers in use
-- uint32_t bufs_used;
--
-- /// Position in the buffer in lzma_outq_read()
-- size_t read_pos;
--
--} lzma_outq;
--
--
--/**
-- * \brief Calculate the memory usage of an output queue
-- *
-- * \return Approximate memory usage in bytes or UINT64_MAX on error.
-- */
--extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
--
--
--/// \brief Initialize an output queue
--///
--/// \param outq Pointer to an output queue. Before calling
--/// this function the first time, *outq should
--/// have been zeroed with memzero() so that this
--/// function knows that there are no previous
--/// allocations to free.
--/// \param allocator Pointer to allocator or NULL
--/// \param buf_size_max Maximum amount of data that a single buffer
--/// in the queue may need to store.
--/// \param threads Number of buffers that may be in use
--/// concurrently. Note that more than this number
--/// of buffers will actually get allocated to
--/// improve performance when buffers finish
--/// out of order.
--///
--/// \return - LZMA_OK
--/// - LZMA_MEM_ERROR
--///
--extern lzma_ret lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
-- uint64_t buf_size_max, uint32_t threads);
--
--
--/// \brief Free the memory associated with the output queue
--extern void lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator);
--
--
--/// \brief Get a new buffer
--///
--/// lzma_outq_has_buf() must be used to check that there is a buffer
--/// available before calling lzma_outq_get_buf().
--///
--extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
--
--
--/// \brief Test if there is data ready to be read
--///
--/// Call to this function must be protected with the same mutex that
--/// is used to protect lzma_outbuf.finished.
--///
--extern bool lzma_outq_is_readable(const lzma_outq *outq);
--
--
--/// \brief Read finished data
--///
--/// \param outq Pointer to an output queue
--/// \param out Beginning of the output buffer
--/// \param out_pos The next byte will be written to
--/// out[*out_pos].
--/// \param out_size Size of the out buffer; the first byte into
--/// which no data is written to is out[out_size].
--/// \param unpadded_size Unpadded Size from the Block encoder
--/// \param uncompressed_size Uncompressed Size from the Block encoder
--///
--/// \return - LZMA: All OK. Either no data was available or the buffer
--/// being read didn't become empty yet.
--/// - LZMA_STREAM_END: The buffer being read was finished.
--/// *unpadded_size and *uncompressed_size were set.
--///
--/// \note This reads lzma_outbuf.finished variables and thus call
--/// to this function needs to be protected with a mutex.
--///
--extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,
-- uint8_t *restrict out, size_t *restrict out_pos,
-- size_t out_size, lzma_vli *restrict unpadded_size,
-- lzma_vli *restrict uncompressed_size);
--
--
--/// \brief Test if there is at least one buffer free
--///
--/// This must be used before getting a new buffer with lzma_outq_get_buf().
--///
--static inline bool
--lzma_outq_has_buf(const lzma_outq *outq)
--{
-- return outq->bufs_used < outq->bufs_allocated;
--}
--
--
--/// \brief Test if the queue is completely empty
--static inline bool
--lzma_outq_is_empty(const lzma_outq *outq)
--{
-- return outq->bufs_used == 0;
--}
-diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
-deleted file mode 100644
-index a4b2800..0000000
---- a/src/liblzma/common/stream_encoder_mt.c
-+++ /dev/null
-@@ -1,1013 +0,0 @@
--///////////////////////////////////////////////////////////////////////////////
--//
--/// \file stream_encoder_mt.c
--/// \brief Multithreaded .xz Stream encoder
--//
--// Author: Lasse Collin
--//
--// This file has been put into the public domain.
--// You can do whatever you want with this file.
--//
--///////////////////////////////////////////////////////////////////////////////
--
--#include "filter_encoder.h"
--#include "easy_preset.h"
--#include "block_encoder.h"
--#include "index_encoder.h"
--#include "outqueue.h"
--
--
--/// Maximum supported block size. This makes it simpler to prevent integer
--/// overflows if we are given unusually large block size.
--#define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)
--
--
--typedef enum {
-- /// Waiting for work.
-- THR_IDLE,
--
-- /// Encoding is in progress.
-- THR_RUN,
--
-- /// Encoding is in progress but no more input data will
-- /// be read.
-- THR_FINISH,
--
-- /// The main thread wants the thread to stop whatever it was doing
-- /// but not exit.
-- THR_STOP,
--
-- /// The main thread wants the thread to exit. We could use
-- /// cancellation but since there's stopped anyway, this is lazier.
-- THR_EXIT,
--
--} worker_state;
--
--
--typedef struct worker_thread_s worker_thread;
--struct worker_thread_s {
-- worker_state state;
--
-- /// Input buffer of coder->block_size bytes. The main thread will
-- /// put new input into this and update in_size accordingly. Once
-- /// no more input is coming, state will be set to THR_FINISH.
-- uint8_t *in;
--
-- /// Amount of data available in the input buffer. This is modified
-- /// only by the main thread.
-- size_t in_size;
--
-- /// Output buffer for this thread. This is set by the main
-- /// thread every time a new Block is started with this thread
-- /// structure.
-- lzma_outbuf *outbuf;
--
-- /// Pointer to the main structure is needed when putting this
-- /// thread back to the stack of free threads.
-- lzma_coder *coder;
--
-- /// The allocator is set by the main thread. Since a copy of the
-- /// pointer is kept here, the application must not change the
-- /// allocator before calling lzma_end().
-- lzma_allocator *allocator;
--
-- /// Block encoder
-- lzma_next_coder block_encoder;
--
-- /// Compression options for this Block
-- lzma_block block_options;
--
-- /// Next structure in the stack of free worker threads.
-- worker_thread *next;
--
-- pthread_mutex_t mutex;
-- pthread_cond_t cond;
--
-- /// The ID of this thread is used to join the thread
-- /// when it's not needed anymore.
-- pthread_t thread_id;
--};
--
--
--struct lzma_coder_s {
-- enum {
-- SEQ_STREAM_HEADER,
-- SEQ_BLOCK,
-- SEQ_INDEX,
-- SEQ_STREAM_FOOTER,
-- } sequence;
--
-- /// Start a new Block every block_size bytes of input unless
-- /// LZMA_FULL_FLUSH or LZMA_FULL_BARRIER is used earlier.
-- size_t block_size;
--
-- /// The filter chain currently in use
-- lzma_filter filters[LZMA_FILTERS_MAX + 1];
--
--
-- /// Index to hold sizes of the Blocks
-- lzma_index *index;
--
-- /// Index encoder
-- lzma_next_coder index_encoder;
--
--
-- /// Stream Flags for encoding the Stream Header and Stream Footer.
-- lzma_stream_flags stream_flags;
--
-- /// Buffer to hold Stream Header and Stream Footer.
-- uint8_t header[LZMA_STREAM_HEADER_SIZE];
--
-- /// Read position in header[]
-- size_t header_pos;
--
--
-- /// Output buffer queue for compressed data
-- lzma_outq outq;
--
--
-- /// True if wait_max is used.
-- bool has_timeout;
--
-- /// Maximum wait time if cannot use all the input and cannot
-- /// fill the output buffer.
-- struct timespec wait_max;
--
--
-- /// Error code from a worker thread
-- lzma_ret thread_error;
--
-- /// Array of allocated thread-specific structures
-- worker_thread *threads;
--
-- /// Number of structures in "threads" above. This is also the
-- /// number of threads that will be created at maximum.
-- uint32_t threads_max;
--
-- /// Number of thread structures that have been initialized, and
-- /// thus the number of worker threads actually created so far.
-- uint32_t threads_initialized;
--
-- /// Stack of free threads. When a thread finishes, it puts itself
-- /// back into this stack. This starts as empty because threads
-- /// are created only when actually needed.
-- worker_thread *threads_free;
--
-- /// The most recent worker thread to which the main thread writes
-- /// the new input from the application.
-- worker_thread *thr;
--
-- pthread_mutex_t mutex;
-- mythread_cond cond;
--};
--
--
--/// Tell the main thread that something has gone wrong.
--static void
--worker_error(worker_thread *thr, lzma_ret ret)
--{
-- assert(ret != LZMA_OK);
-- assert(ret != LZMA_STREAM_END);
--
-- mythread_sync(thr->coder->mutex) {
-- if (thr->coder->thread_error == LZMA_OK)
-- thr->coder->thread_error = ret;
--
-- mythread_cond_signal(&thr->coder->cond);
-- }
--
-- return;
--}
--
--
--static worker_state
--worker_encode(worker_thread *thr, worker_state state)
--{
-- // Set the Block options.
-- thr->block_options = (lzma_block){
-- .version = 0,
-- .check = thr->coder->stream_flags.check,
-- .compressed_size = thr->coder->outq.buf_size_max,
-- .uncompressed_size = thr->coder->block_size,
--
-- // TODO: To allow changing the filter chain, the filters
-- // array must be copied to each worker_thread.
-- .filters = thr->coder->filters,
-- };
--
-- // Calculate maximum size of the Block Header. This amount is
-- // reserved in the beginning of the buffer so that Block Header
-- // along with Compressed Size and Uncompressed Size can be
-- // written there.
-- lzma_ret ret = lzma_block_header_size(&thr->block_options);
-- if (ret != LZMA_OK) {
-- worker_error(thr, ret);
-- return THR_STOP;
-- }
--
-- // Initialize the Block encoder.
-- ret = lzma_block_encoder_init(&thr->block_encoder,
-- thr->allocator, &thr->block_options);
-- if (ret != LZMA_OK) {
-- worker_error(thr, ret);
-- return THR_STOP;
-- }
--
-- size_t in_pos = 0;
-- size_t in_size = 0;
--
-- thr->outbuf->size = thr->block_options.header_size;
-- const size_t out_size = thr->coder->outq.buf_size_max;
--
-- do {
-- mythread_sync(thr->mutex) {
-- while (in_size == thr->in_size
-- && thr->state == THR_RUN)
-- pthread_cond_wait(&thr->cond, &thr->mutex);
--
-- state = thr->state;
-- in_size = thr->in_size;
--
-- // TODO? Store in_pos and out_pos into *thr here
-- // so that the application may read them via
-- // some currently non-existing function to get
-- // progress information.
-- }
--
-- // Return if we were asked to stop or exit.
-- if (state >= THR_STOP)
-- return state;
--
-- lzma_action action = state == THR_FINISH
-- ? LZMA_FINISH : LZMA_RUN;
--
-- // Limit the amount of input given to the Block encoder
-- // at once. This way this thread can react fairly quickly
-- // if the main thread wants us to stop or exit.
-- static const size_t in_chunk_max = 16384;
-- size_t in_limit = in_size;
-- if (in_size - in_pos > in_chunk_max) {
-- in_limit = in_pos + in_chunk_max;
-- action = LZMA_RUN;
-- }
--
-- ret = thr->block_encoder.code(
-- thr->block_encoder.coder, thr->allocator,
-- thr->in, &in_pos, in_limit, thr->outbuf->buf,
-- &thr->outbuf->size, out_size, action);
-- } while (ret == LZMA_OK);
--
-- if (ret != LZMA_STREAM_END) {
-- worker_error(thr, ret);
-- return THR_STOP;
-- }
--
-- assert(state == THR_FINISH);
--
-- // Encode the Block Header. By doing it after the compression,
-- // we can store the Compressed Size and Uncompressed Size fields.
-- ret = lzma_block_header_encode(&thr->block_options, thr->outbuf->buf);
-- if (ret != LZMA_OK) {
-- worker_error(thr, ret);
-- return THR_STOP;
-- }
--
-- // Set the size information that will be read by the main thread
-- // to write the Index field.
-- thr->outbuf->unpadded_size
-- = lzma_block_unpadded_size(&thr->block_options);
-- assert(thr->outbuf->unpadded_size != 0);
-- thr->outbuf->uncompressed_size = thr->block_options.uncompressed_size;
--
-- return THR_FINISH;
--}
--
--
--static void *
--worker_start(void *thr_ptr)
--{
-- worker_thread *thr = thr_ptr;
-- worker_state state = THR_IDLE; // Init to silence a warning
--
-- while (true) {
-- // Wait for work.
-- mythread_sync(thr->mutex) {
-- while (true) {
-- // The thread is already idle so if we are
-- // requested to stop, just set the state.
-- if (thr->state == THR_STOP) {
-- thr->state = THR_IDLE;
-- pthread_cond_signal(&thr->cond);
-- }
--
-- state = thr->state;
-- if (state != THR_IDLE)
-- break;
--
-- pthread_cond_wait(&thr->cond, &thr->mutex);
-- }
-- }
--
-- assert(state != THR_IDLE);
-- assert(state != THR_STOP);
--
-- if (state <= THR_FINISH)
-- state = worker_encode(thr, state);
--
-- if (state == THR_EXIT)
-- break;
--
-- // Mark the thread as idle. Signal is needed for the case
-- // where the main thread is waiting for the threads to stop.
-- mythread_sync(thr->mutex) {
-- thr->state = THR_IDLE;
-- pthread_cond_signal(&thr->cond);
-- }
--
-- mythread_sync(thr->coder->mutex) {
-- // Mark the output buffer as finished if
-- // no errors occurred.
-- thr->outbuf->finished = state == THR_FINISH;
--
-- // Return this thread to the stack of free threads.
-- thr->next = thr->coder->threads_free;
-- thr->coder->threads_free = thr;
--
-- mythread_cond_signal(&thr->coder->cond);
-- }
-- }
--
-- // Exiting, free the resources.
-- pthread_mutex_destroy(&thr->mutex);
-- pthread_cond_destroy(&thr->cond);
--
-- lzma_next_end(&thr->block_encoder, thr->allocator);
-- lzma_free(thr->in, thr->allocator);
-- return NULL;
--}
--
--
--/// Make the threads stop but not exit. Optionally wait for them to stop.
--static void
--threads_stop(lzma_coder *coder, bool wait)
--{
-- // Tell the threads to stop.
-- for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
-- mythread_sync(coder->threads[i].mutex) {
-- coder->threads[i].state = THR_STOP;
-- pthread_cond_signal(&coder->threads[i].cond);
-- }
-- }
--
-- if (!wait)
-- return;
--
-- // Wait for the threads to settle in the idle state.
-- for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
-- mythread_sync(coder->threads[i].mutex) {
-- while (coder->threads[i].state != THR_IDLE)
-- pthread_cond_wait(&coder->threads[i].cond,
-- &coder->threads[i].mutex);
-- }
-- }
--
-- return;
--}
--
--
--/// Stop the threads and free the resources associated with them.
--/// Wait until the threads have exited.
--static void
--threads_end(lzma_coder *coder, lzma_allocator *allocator)
--{
-- for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
-- mythread_sync(coder->threads[i].mutex) {
-- coder->threads[i].state = THR_EXIT;
-- pthread_cond_signal(&coder->threads[i].cond);
-- }
-- }
--
-- for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
-- int ret = pthread_join(coder->threads[i].thread_id, NULL);
-- assert(ret == 0);
-- (void)ret;
-- }
--
-- lzma_free(coder->threads, allocator);
-- return;
--}
--
--
--/// Initialize a new worker_thread structure and create a new thread.
--static lzma_ret
--initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
--{
-- worker_thread *thr = &coder->threads[coder->threads_initialized];
--
-- thr->in = lzma_alloc(coder->block_size, allocator);
-- if (thr->in == NULL)
-- return LZMA_MEM_ERROR;
--
-- if (pthread_mutex_init(&thr->mutex, NULL))
-- goto error_mutex;
--
-- if (pthread_cond_init(&thr->cond, NULL))
-- goto error_cond;
--
-- thr->state = THR_IDLE;
-- thr->allocator = allocator;
-- thr->coder = coder;
-- thr->block_encoder = LZMA_NEXT_CODER_INIT;
--
-- if (mythread_create(&thr->thread_id, &worker_start, thr))
-- goto error_thread;
--
-- ++coder->threads_initialized;
-- coder->thr = thr;
--
-- return LZMA_OK;
--
--error_thread:
-- pthread_cond_destroy(&thr->cond);
--
--error_cond:
-- pthread_mutex_destroy(&thr->mutex);
--
--error_mutex:
-- lzma_free(thr->in, allocator);
-- return LZMA_MEM_ERROR;
--}
--
--
--static lzma_ret
--get_thread(lzma_coder *coder, lzma_allocator *allocator)
--{
-- // If there are no free output subqueues, there is no
-- // point to try getting a thread.
-- if (!lzma_outq_has_buf(&coder->outq))
-- return LZMA_OK;
--
-- // If there is a free structure on the stack, use it.
-- mythread_sync(coder->mutex) {
-- if (coder->threads_free != NULL) {
-- coder->thr = coder->threads_free;
-- coder->threads_free = coder->threads_free->next;
-- }
-- }
--
-- if (coder->thr == NULL) {
-- // If there are no uninitialized structures left, return.
-- if (coder->threads_initialized == coder->threads_max)
-- return LZMA_OK;
--
-- // Initialize a new thread.
-- return_if_error(initialize_new_thread(coder, allocator));
-- }
--
-- // Reset the parts of the thread state that have to be done
-- // in the main thread.
-- mythread_sync(coder->thr->mutex) {
-- coder->thr->state = THR_RUN;
-- coder->thr->in_size = 0;
-- coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);
-- pthread_cond_signal(&coder->thr->cond);
-- }
--
-- return LZMA_OK;
--}
--
--
--static lzma_ret
--stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
-- const uint8_t *restrict in, size_t *restrict in_pos,
-- size_t in_size, lzma_action action)
--{
-- while (*in_pos < in_size
-- || (coder->thr != NULL && action != LZMA_RUN)) {
-- if (coder->thr == NULL) {
-- // Get a new thread.
-- const lzma_ret ret = get_thread(coder, allocator);
-- if (coder->thr == NULL)
-- return ret;
-- }
--
-- // Copy the input data to thread's buffer.
-- size_t thr_in_size = coder->thr->in_size;
-- lzma_bufcpy(in, in_pos, in_size, coder->thr->in,
-- &thr_in_size, coder->block_size);
--
-- // Tell the Block encoder to finish if
-- // - it has got block_size bytes of input; or
-- // - all input was used and LZMA_FINISH, LZMA_FULL_FLUSH,
-- // or LZMA_FULL_BARRIER was used.
-- //
-- // TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
-- const bool finish = thr_in_size == coder->block_size
-- || (*in_pos == in_size && action != LZMA_RUN);
--
-- bool block_error = false;
--
-- mythread_sync(coder->thr->mutex) {
-- if (coder->thr->state == THR_IDLE) {
-- // Something has gone wrong with the Block
-- // encoder. It has set coder->thread_error
-- // which we will read a few lines later.
-- block_error = true;
-- } else {
-- // Tell the Block encoder its new amount
-- // of input and update the state if needed.
-- coder->thr->in_size = thr_in_size;
--
-- if (finish)
-- coder->thr->state = THR_FINISH;
--
-- pthread_cond_signal(&coder->thr->cond);
-- }
-- }
--
-- if (block_error) {
-- lzma_ret ret;
--
-- mythread_sync(coder->mutex) {
-- ret = coder->thread_error;
-- }
--
-- return ret;
-- }
--
-- if (finish)
-- coder->thr = NULL;
-- }
--
-- return LZMA_OK;
--}
--
--
--/// Wait until more input can be consumed, more output can be read, or
--/// an optional timeout is reached.
--static bool
--wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
-- bool *has_blocked, bool has_input)
--{
-- if (coder->has_timeout && !*has_blocked) {
-- // Every time when stream_encode_mt() is called via
-- // lzma_code(), *has_block starts as false. We set it
-- // to true here and calculate the absolute time when
-- // we must return if there's nothing to do.
-- //
-- // The idea of *has_blocked is to avoid unneeded calls
-- // to mythread_cond_abstime(), which may do a syscall
-- // depending on the operating system.
-- *has_blocked = true;
-- *wait_abs = coder->wait_max;
-- mythread_cond_abstime(&coder->cond, wait_abs);
-- }
--
-- bool timed_out = false;
--
-- mythread_sync(coder->mutex) {
-- // There are four things that we wait. If one of them
-- // becomes possible, we return.
-- // - If there is input left, we need to get a free
-- // worker thread and an output buffer for it.
-- // - Data ready to be read from the output queue.
-- // - A worker thread indicates an error.
-- // - Time out occurs.
-- while ((!has_input || coder->threads_free == NULL
-- || !lzma_outq_has_buf(&coder->outq))
-- && !lzma_outq_is_readable(&coder->outq)
-- && coder->thread_error == LZMA_OK
-- && !timed_out) {
-- if (coder->has_timeout)
-- timed_out = mythread_cond_timedwait(
-- &coder->cond, &coder->mutex,
-- wait_abs) != 0;
-- else
-- mythread_cond_wait(&coder->cond,
-- &coder->mutex);
-- }
-- }
--
-- return timed_out;
--}
--
--
--static lzma_ret
--stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
-- const uint8_t *restrict in, size_t *restrict in_pos,
-- size_t in_size, uint8_t *restrict out,
-- size_t *restrict out_pos, size_t out_size, lzma_action action)
--{
-- switch (coder->sequence) {
-- case SEQ_STREAM_HEADER:
-- lzma_bufcpy(coder->header, &coder->header_pos,
-- sizeof(coder->header),
-- out, out_pos, out_size);
-- if (coder->header_pos < sizeof(coder->header))
-- return LZMA_OK;
--
-- coder->header_pos = 0;
-- coder->sequence = SEQ_BLOCK;
--
-- // Fall through
--
-- case SEQ_BLOCK: {
-- // Initialized to silence warnings.
-- lzma_vli unpadded_size = 0;
-- lzma_vli uncompressed_size = 0;
-- lzma_ret ret = LZMA_OK;
--
-- // These are for wait_for_work().
-- bool has_blocked = false;
-- struct timespec wait_abs;
--
-- while (true) {
-- mythread_sync(coder->mutex) {
-- // Check for Block encoder errors.
-- ret = coder->thread_error;
-- if (ret != LZMA_OK) {
-- assert(ret != LZMA_STREAM_END);
-- break;
-- }
--
-- // Try to read compressed data to out[].
-- ret = lzma_outq_read(&coder->outq,
-- out, out_pos, out_size,
-- &unpadded_size,
-- &uncompressed_size);
-- }
--
-- if (ret == LZMA_STREAM_END) {
-- // End of Block. Add it to the Index.
-- ret = lzma_index_append(coder->index,
-- allocator, unpadded_size,
-- uncompressed_size);
--
-- // If we didn't fill the output buffer yet,
-- // try to read more data. Maybe the next
-- // outbuf has been finished already too.
-- if (*out_pos < out_size)
-- continue;
-- }
--
-- if (ret != LZMA_OK) {
-- // coder->thread_error was set or
-- // lzma_index_append() failed.
-- threads_stop(coder, false);
-- return ret;
-- }
--
-- // Check if the last Block was finished.
-- if (action == LZMA_FINISH
-- && *in_pos == in_size
-- && lzma_outq_is_empty(
-- &coder->outq))
-- break;
--
-- // Try to give uncompressed data to a worker thread.
-- ret = stream_encode_in(coder, allocator,
-- in, in_pos, in_size, action);
-- if (ret != LZMA_OK) {
-- threads_stop(coder, false);
-- return ret;
-- }
--
-- // Return if
-- // - we have used all the input and expect to
-- // get more input; or
-- // - the output buffer has been filled.
-- //
-- // TODO: Support flushing.
-- if ((*in_pos == in_size && action != LZMA_FINISH)
-- || *out_pos == out_size)
-- return LZMA_OK;
--
-- // Neither in nor out has been used completely.
-- // Wait until there's something we can do.
-- if (wait_for_work(coder, &wait_abs, &has_blocked,
-- *in_pos < in_size))
-- return LZMA_TIMED_OUT;
-- }
--
-- // All Blocks have been encoded and the threads have stopped.
-- // Prepare to encode the Index field.
-- return_if_error(lzma_index_encoder_init(
-- &coder->index_encoder, allocator,
-- coder->index));
-- coder->sequence = SEQ_INDEX;
-- }
--
-- // Fall through
--
-- case SEQ_INDEX: {
-- // Call the Index encoder. It doesn't take any input, so
-- // those pointers can be NULL.
-- const lzma_ret ret = coder->index_encoder.code(
-- coder->index_encoder.coder, allocator,
-- NULL, NULL, 0,
-- out, out_pos, out_size, LZMA_RUN);
-- if (ret != LZMA_STREAM_END)
-- return ret;
--
-- // Encode the Stream Footer into coder->buffer.
-- coder->stream_flags.backward_size
-- = lzma_index_size(coder->index);
-- if (lzma_stream_footer_encode(&coder->stream_flags,
-- coder->header) != LZMA_OK)
-- return LZMA_PROG_ERROR;
--
-- coder->sequence = SEQ_STREAM_FOOTER;
-- }
--
-- // Fall through
--
-- case SEQ_STREAM_FOOTER:
-- lzma_bufcpy(coder->header, &coder->header_pos,
-- sizeof(coder->header),
-- out, out_pos, out_size);
-- return coder->header_pos < sizeof(coder->header)
-- ? LZMA_OK : LZMA_STREAM_END;
-- }
--
-- assert(0);
-- return LZMA_PROG_ERROR;
--}
--
--
--static void
--stream_encoder_mt_end(lzma_coder *coder, lzma_allocator *allocator)
--{
-- // Threads must be killed before the output queue can be freed.
-- threads_end(coder, allocator);
-- lzma_outq_end(&coder->outq, allocator);
--
-- for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
-- lzma_free(coder->filters[i].options, allocator);
--
-- lzma_next_end(&coder->index_encoder, allocator);
-- lzma_index_end(coder->index, allocator);
--
-- mythread_cond_destroy(&coder->cond);
-- pthread_mutex_destroy(&coder->mutex);
--
-- lzma_free(coder, allocator);
-- return;
--}
--
--
--/// Options handling for lzma_stream_encoder_mt_init() and
--/// lzma_stream_encoder_mt_memusage()
--static lzma_ret
--get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
-- const lzma_filter **filters, uint64_t *block_size,
-- uint64_t *outbuf_size_max)
--{
-- // Validate some of the options.
-- if (options == NULL)
-- return LZMA_PROG_ERROR;
--
-- if (options->flags != 0 || options->threads == 0
-- || options->threads > LZMA_THREADS_MAX)
-- return LZMA_OPTIONS_ERROR;
--
-- if (options->filters != NULL) {
-- // Filter chain was given, use it as is.
-- *filters = options->filters;
-- } else {
-- // Use a preset.
-- if (lzma_easy_preset(opt_easy, options->preset))
-- return LZMA_OPTIONS_ERROR;
--
-- *filters = opt_easy->filters;
-- }
--
-- // Block size
-- if (options->block_size > 0) {
-- if (options->block_size > BLOCK_SIZE_MAX)
-- return LZMA_OPTIONS_ERROR;
--
-- *block_size = options->block_size;
-- } else {
-- // Determine the Block size from the filter chain.
-- *block_size = lzma_mt_block_size(*filters);
-- if (*block_size == 0)
-- return LZMA_OPTIONS_ERROR;
--
-- assert(*block_size <= BLOCK_SIZE_MAX);
-- }
--
-- // Calculate the maximum amount output that a single output buffer
-- // may need to hold. This is the same as the maximum total size of
-- // a Block.
-- //
-- // FIXME: As long as the encoder keeps the whole input buffer
-- // available and doesn't start writing output before finishing
-- // the Block, it could use lzma_stream_buffer_bound() and use
-- // uncompressed LZMA2 chunks if the data doesn't compress.
-- *outbuf_size_max = *block_size + *block_size / 16 + 16384;
--
-- return LZMA_OK;
--}
--
--
--static lzma_ret
--stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
-- const lzma_mt *options)
--{
-- lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);
--
-- // Get the filter chain.
-- lzma_options_easy easy;
-- const lzma_filter *filters;
-- uint64_t block_size;
-- uint64_t outbuf_size_max;
-- return_if_error(get_options(options, &easy, &filters,
-- &block_size, &outbuf_size_max));
--
--#if SIZE_MAX < UINT64_MAX
-- if (block_size > SIZE_MAX)
-- return LZMA_MEM_ERROR;
--#endif
--
-- // FIXME TODO: Validate the filter chain so that we can give
-- // an error in this function instead of delaying it to the first
-- // call to lzma_code().
--
-- // Validate the Check ID.
-- if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
-- return LZMA_PROG_ERROR;
--
-- if (!lzma_check_is_supported(options->check))
-- return LZMA_UNSUPPORTED_CHECK;
--
-- // Allocate and initialize the base structure if needed.
-- if (next->coder == NULL) {
-- next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
-- if (next->coder == NULL)
-- return LZMA_MEM_ERROR;
--
-- // For the mutex and condition variable initializations
-- // the error handling has to be done here because
-- // stream_encoder_mt_end() doesn't know if they have
-- // already been initialized or not.
-- if (pthread_mutex_init(&next->coder->mutex, NULL)) {
-- lzma_free(next->coder, allocator);
-- next->coder = NULL;
-- return LZMA_MEM_ERROR;
-- }
--
-- if (mythread_cond_init(&next->coder->cond)) {
-- pthread_mutex_destroy(&next->coder->mutex);
-- lzma_free(next->coder, allocator);
-- next->coder = NULL;
-- return LZMA_MEM_ERROR;
-- }
--
-- next->code = &stream_encode_mt;
-- next->end = &stream_encoder_mt_end;
--// next->update = &stream_encoder_mt_update;
--
-- next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
-- next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
-- next->coder->index = NULL;
-- memzero(&next->coder->outq, sizeof(next->coder->outq));
-- next->coder->threads = NULL;
-- next->coder->threads_max = 0;
-- next->coder->threads_initialized = 0;
-- }
--
-- // Basic initializations
-- next->coder->sequence = SEQ_STREAM_HEADER;
-- next->coder->block_size = (size_t)(block_size);
-- next->coder->thread_error = LZMA_OK;
-- next->coder->thr = NULL;
--
-- // Allocate the thread-specific base structures.
-- assert(options->threads > 0);
-- if (next->coder->threads_max != options->threads) {
-- threads_end(next->coder, allocator);
--
-- next->coder->threads = NULL;
-- next->coder->threads_max = 0;
--
-- next->coder->threads_initialized = 0;
-- next->coder->threads_free = NULL;
--
-- next->coder->threads = lzma_alloc(
-- options->threads * sizeof(worker_thread),
-- allocator);
-- if (next->coder->threads == NULL)
-- return LZMA_MEM_ERROR;
--
-- next->coder->threads_max = options->threads;
-- } else {
-- // Reuse the old structures and threads. Tell the running
-- // threads to stop and wait until they have stopped.
-- threads_stop(next->coder, true);
-- }
--
-- // Output queue
-- return_if_error(lzma_outq_init(&next->coder->outq, allocator,
-- outbuf_size_max, options->threads));
--
-- // Timeout
-- if (options->timeout > 0) {
-- next->coder->wait_max.tv_sec = options->timeout / 1000;
-- next->coder->wait_max.tv_nsec
-- = (options->timeout % 1000) * 1000000L;
-- next->coder->has_timeout = true;
-- } else {
-- next->coder->has_timeout = false;
-- }
--
-- // Free the old filter chain and copy the new one.
-- for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
-- lzma_free(next->coder->filters[i].options, allocator);
--
-- return_if_error(lzma_filters_copy(options->filters,
-- next->coder->filters, allocator));
--
-- // Index
-- lzma_index_end(next->coder->index, allocator);
-- next->coder->index = lzma_index_init(allocator);
-- if (next->coder->index == NULL)
-- return LZMA_MEM_ERROR;
--
-- // Stream Header
-- next->coder->stream_flags.version = 0;
-- next->coder->stream_flags.check = options->check;
-- return_if_error(lzma_stream_header_encode(
-- &next->coder->stream_flags, next->coder->header));
--
-- next->coder->header_pos = 0;
--
-- return LZMA_OK;
--}
--
--
--extern LZMA_API(lzma_ret)
--lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)
--{
-- lzma_next_strm_init(stream_encoder_mt_init, strm, options);
--
-- strm->internal->supported_actions[LZMA_RUN] = true;
--// strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
--// strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
--// strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
-- strm->internal->supported_actions[LZMA_FINISH] = true;
--
-- return LZMA_OK;
--}
--
--
--// This function name is a monster but it's consistent with the older
--// monster names. :-( 31 chars is the max that C99 requires so in that
--// sense it's not too long. ;-)
--extern LZMA_API(uint64_t)
--lzma_stream_encoder_mt_memusage(const lzma_mt *options)
--{
-- lzma_options_easy easy;
-- const lzma_filter *filters;
-- uint64_t block_size;
-- uint64_t outbuf_size_max;
--
-- if (get_options(options, &easy, &filters, &block_size,
-- &outbuf_size_max) != LZMA_OK)
-- return UINT64_MAX;
--
-- // Memory usage of the input buffers
-- const uint64_t inbuf_memusage = options->threads * block_size;
--
-- // Memory usage of the filter encoders
-- uint64_t filters_memusage
-- = lzma_raw_encoder_memusage(options->filters);
-- if (filters_memusage == UINT64_MAX)
-- return UINT64_MAX;
--
-- filters_memusage *= options->threads;
--
-- // Memory usage of the output queue
-- const uint64_t outq_memusage = lzma_outq_memusage(
-- outbuf_size_max, options->threads);
-- if (outq_memusage == UINT64_MAX)
-- return UINT64_MAX;
--
-- // Sum them with overflow checking.
-- uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
-- + options->threads * sizeof(worker_thread);
--
-- if (UINT64_MAX - total_memusage < inbuf_memusage)
-- return UINT64_MAX;
--
-- total_memusage += inbuf_memusage;
--
-- if (UINT64_MAX - total_memusage < filters_memusage)
-- return UINT64_MAX;
--
-- total_memusage += filters_memusage;
--
-- if (UINT64_MAX - total_memusage < outq_memusage)
-- return UINT64_MAX;
--
-- return total_memusage + outq_memusage;
--}
-diff --git a/src/xz/args.c b/src/xz/args.c
-index dea93c5..f207e7f 100644
---- a/src/xz/args.c
-+++ b/src/xz/args.c
-@@ -179,9 +179,8 @@ parse_real(args_info *args, int argc, char **argv)
- break;
-
- case 'T':
-- // The max is from src/liblzma/common/common.h.
-- hardware_threads_set(str_to_uint64("threads",
-- optarg, 0, 16384));
-+ hardware_threadlimit_set(str_to_uint64(
-+ "threads", optarg, 0, UINT32_MAX));
- break;
-
- // --version
-diff --git a/src/xz/coder.c b/src/xz/coder.c
-index 41193a7..4139da4 100644
---- a/src/xz/coder.c
-+++ b/src/xz/coder.c
-@@ -55,14 +55,6 @@ static lzma_check check;
- /// This becomes false if the --check=CHECK option is used.
- static bool check_default = true;
-
--#ifdef HAVE_PTHREAD
--static lzma_mt mt_options = {
-- .flags = 0,
-- .timeout = 300,
-- .filters = filters,
--};
--#endif
--
-
- extern void
- coder_set_check(lzma_check new_check)
-@@ -125,15 +117,6 @@ memlimit_too_small(uint64_t memory_usage)
- extern void
- coder_set_compression_settings(void)
- {
-- // The default check type is CRC64, but fallback to CRC32
-- // if CRC64 isn't supported by the copy of liblzma we are
-- // using. CRC32 is always supported.
-- if (check_default) {
-- check = LZMA_CHECK_CRC64;
-- if (!lzma_check_is_supported(check))
-- check = LZMA_CHECK_CRC32;
-- }
--
- // Options for LZMA1 or LZMA2 in case we are using a preset.
- static lzma_options_lzma opt_lzma;
-
-@@ -187,30 +170,15 @@ coder_set_compression_settings(void)
- // Print the selected filter chain.
- message_filters_show(V_DEBUG, filters);
-
-- // Get the memory usage. Note that if --format=raw was used,
-- // we can be decompressing.
-+ // If using --format=raw, we can be decoding. The memusage function
-+ // also validates the filter chain and the options used for the
-+ // filters.
- const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
- uint64_t memory_usage;
-- if (opt_mode == MODE_COMPRESS) {
--#ifdef HAVE_PTHREAD
-- if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
-- mt_options.threads = hardware_threads_get();
-- mt_options.block_size = opt_block_size;
-- mt_options.check = check;
-- memory_usage = lzma_stream_encoder_mt_memusage(
-- &mt_options);
-- if (memory_usage != UINT64_MAX)
-- message(V_DEBUG, _("Using up to %" PRIu32
-- " threads."),
-- mt_options.threads);
-- } else
--#endif
-- {
-- memory_usage = lzma_raw_encoder_memusage(filters);
-- }
-- } else {
-+ if (opt_mode == MODE_COMPRESS)
-+ memory_usage = lzma_raw_encoder_memusage(filters);
-+ else
- memory_usage = lzma_raw_decoder_memusage(filters);
-- }
-
- if (memory_usage == UINT64_MAX)
- message_fatal(_("Unsupported filter chain or filter options"));
-@@ -226,99 +194,90 @@ coder_set_compression_settings(void)
- round_up_to_mib(decmem), 0));
- }
-
-- if (memory_usage <= memory_limit)
-- return;
-+ if (memory_usage > memory_limit) {
-+ // If --no-auto-adjust was used or we didn't find LZMA1 or
-+ // LZMA2 as the last filter, give an error immediately.
-+ // --format=raw implies --no-auto-adjust.
-+ if (!opt_auto_adjust || opt_format == FORMAT_RAW)
-+ memlimit_too_small(memory_usage);
-
-- // If --no-auto-adjust was used or we didn't find LZMA1 or
-- // LZMA2 as the last filter, give an error immediately.
-- // --format=raw implies --no-auto-adjust.
-- if (!opt_auto_adjust || opt_format == FORMAT_RAW)
-- memlimit_too_small(memory_usage);
-+ assert(opt_mode == MODE_COMPRESS);
-
-- assert(opt_mode == MODE_COMPRESS);
-+ // Look for the last filter if it is LZMA2 or LZMA1, so
-+ // we can make it use less RAM. With other filters we don't
-+ // know what to do.
-+ size_t i = 0;
-+ while (filters[i].id != LZMA_FILTER_LZMA2
-+ && filters[i].id != LZMA_FILTER_LZMA1) {
-+ if (filters[i].id == LZMA_VLI_UNKNOWN)
-+ memlimit_too_small(memory_usage);
-+
-+ ++i;
-+ }
-
--#ifdef HAVE_PTHREAD
-- if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
-- // Try to reduce the number of threads before
-- // adjusting the compression settings down.
-- do {
-- // FIXME? The real single-threaded mode has
-- // lower memory usage, but it's not comparable
-- // because it doesn't write the size info
-- // into Block Headers.
-- if (--mt_options.threads == 0)
-+ // Decrease the dictionary size until we meet the memory
-+ // usage limit. First round down to full mebibytes.
-+ lzma_options_lzma *opt = filters[i].options;
-+ const uint32_t orig_dict_size = opt->dict_size;
-+ opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
-+ while (true) {
-+ // If it is below 1 MiB, auto-adjusting failed. We
-+ // could be more sophisticated and scale it down even
-+ // more, but let's see if many complain about this
-+ // version.
-+ //
-+ // FIXME: Displays the scaled memory usage instead
-+ // of the original.
-+ if (opt->dict_size < (UINT32_C(1) << 20))
- memlimit_too_small(memory_usage);
-
-- memory_usage = lzma_stream_encoder_mt_memusage(
-- &mt_options);
-+ memory_usage = lzma_raw_encoder_memusage(filters);
- if (memory_usage == UINT64_MAX)
- message_bug();
-
-- } while (memory_usage > memory_limit);
--
-- message(V_WARNING, _("Adjusted the number of threads "
-- "from %s to %s to not exceed "
-- "the memory usage limit of %s MiB"),
-- uint64_to_str(hardware_threads_get(), 0),
-- uint64_to_str(mt_options.threads, 1),
-- uint64_to_str(round_up_to_mib(
-- memory_limit), 2));
-+ // Accept it if it is low enough.
-+ if (memory_usage <= memory_limit)
-+ break;
-+
-+ // Otherwise 1 MiB down and try again. I hope this
-+ // isn't too slow method for cases where the original
-+ // dict_size is very big.
-+ opt->dict_size -= UINT32_C(1) << 20;
-+ }
-+
-+ // Tell the user that we decreased the dictionary size.
-+ message(V_WARNING, _("Adjusted LZMA%c dictionary size "
-+ "from %s MiB to %s MiB to not exceed "
-+ "the memory usage limit of %s MiB"),
-+ filters[i].id == LZMA_FILTER_LZMA2
-+ ? '2' : '1',
-+ uint64_to_str(orig_dict_size >> 20, 0),
-+ uint64_to_str(opt->dict_size >> 20, 1),
-+ uint64_to_str(round_up_to_mib(
-+ memory_limit), 2));
- }
--#endif
--
-- if (memory_usage <= memory_limit)
-- return;
--
-- // Look for the last filter if it is LZMA2 or LZMA1, so we can make
-- // it use less RAM. With other filters we don't know what to do.
-- size_t i = 0;
-- while (filters[i].id != LZMA_FILTER_LZMA2
-- && filters[i].id != LZMA_FILTER_LZMA1) {
-- if (filters[i].id == LZMA_VLI_UNKNOWN)
-- memlimit_too_small(memory_usage);
-
-- ++i;
-+/*
-+ // Limit the number of worker threads so that memory usage
-+ // limit isn't exceeded.
-+ assert(memory_usage > 0);
-+ size_t thread_limit = memory_limit / memory_usage;
-+ if (thread_limit == 0)
-+ thread_limit = 1;
-+
-+ if (opt_threads > thread_limit)
-+ opt_threads = thread_limit;
-+*/
-+
-+ if (check_default) {
-+ // The default check type is CRC64, but fallback to CRC32
-+ // if CRC64 isn't supported by the copy of liblzma we are
-+ // using. CRC32 is always supported.
-+ check = LZMA_CHECK_CRC64;
-+ if (!lzma_check_is_supported(check))
-+ check = LZMA_CHECK_CRC32;
- }
-
-- // Decrease the dictionary size until we meet the memory
-- // usage limit. First round down to full mebibytes.
-- lzma_options_lzma *opt = filters[i].options;
-- const uint32_t orig_dict_size = opt->dict_size;
-- opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
-- while (true) {
-- // If it is below 1 MiB, auto-adjusting failed. We could be
-- // more sophisticated and scale it down even more, but let's
-- // see if many complain about this version.
-- //
-- // FIXME: Displays the scaled memory usage instead
-- // of the original.
-- if (opt->dict_size < (UINT32_C(1) << 20))
-- memlimit_too_small(memory_usage);
--
-- memory_usage = lzma_raw_encoder_memusage(filters);
-- if (memory_usage == UINT64_MAX)
-- message_bug();
--
-- // Accept it if it is low enough.
-- if (memory_usage <= memory_limit)
-- break;
--
-- // Otherwise 1 MiB down and try again. I hope this
-- // isn't too slow method for cases where the original
-- // dict_size is very big.
-- opt->dict_size -= UINT32_C(1) << 20;
-- }
--
-- // Tell the user that we decreased the dictionary size.
-- message(V_WARNING, _("Adjusted LZMA%c dictionary size "
-- "from %s MiB to %s MiB to not exceed "
-- "the memory usage limit of %s MiB"),
-- filters[i].id == LZMA_FILTER_LZMA2
-- ? '2' : '1',
-- uint64_to_str(orig_dict_size >> 20, 0),
-- uint64_to_str(opt->dict_size >> 20, 1),
-- uint64_to_str(round_up_to_mib(memory_limit), 2));
--
- return;
- }
-
-@@ -400,14 +359,7 @@ coder_init(file_pair *pair)
- break;
-
- case FORMAT_XZ:
--#ifdef HAVE_PTHREAD
-- if (hardware_threads_get() > 1)
-- ret = lzma_stream_encoder_mt(
-- &strm, &mt_options);
-- else
--#endif
-- ret = lzma_stream_encoder(
-- &strm, filters, check);
-+ ret = lzma_stream_encoder(&strm, filters, check);
- break;
-
- case FORMAT_LZMA:
-@@ -528,8 +480,8 @@ coder_normal(file_pair *pair)
- // to the .xz format. If block_remaining == UINT64_MAX, only
- // a single block is created.
- uint64_t block_remaining = UINT64_MAX;
-- if (hardware_threads_get() == 1 && opt_mode == MODE_COMPRESS
-- && opt_format == FORMAT_XZ && opt_block_size > 0)
-+ if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ
-+ && opt_block_size > 0)
- block_remaining = opt_block_size;
-
- strm.next_out = out_buf.u8;
-diff --git a/src/xz/hardware.c b/src/xz/hardware.c
-index 925926c..a4733c2 100644
---- a/src/xz/hardware.c
-+++ b/src/xz/hardware.c
-@@ -14,9 +14,9 @@
- #include "tuklib_cpucores.h"
-
-
--/// Maximum number of worker threads. This can be set with
-+/// Maximum number of free *coder* threads. This can be set with
- /// the --threads=NUM command line option.
--static uint32_t threads_max = 1;
-+static uint32_t threadlimit;
-
- /// Memory usage limit for compression
- static uint64_t memlimit_compress;
-@@ -29,16 +29,15 @@ static uint64_t total_ram;
-
-
- extern void
--hardware_threads_set(uint32_t n)
-+hardware_threadlimit_set(uint32_t new_threadlimit)
- {
-- if (n == 0) {
-- // Automatic number of threads was requested.
-- // Use the number of available CPU cores.
-- threads_max = tuklib_cpucores();
-- if (threads_max == 0)
-- threads_max = 1;
-+ if (new_threadlimit == 0) {
-+ // The default is the number of available CPU cores.
-+ threadlimit = tuklib_cpucores();
-+ if (threadlimit == 0)
-+ threadlimit = 1;
- } else {
-- threads_max = n;
-+ threadlimit = new_threadlimit;
- }
-
- return;
-@@ -46,9 +45,9 @@ hardware_threads_set(uint32_t n)
-
-
- extern uint32_t
--hardware_threads_get(void)
-+hardware_threadlimit_get(void)
- {
-- return threads_max;
-+ return threadlimit;
- }
-
-
-@@ -140,5 +139,6 @@ hardware_init(void)
-
- // Set the defaults.
- hardware_memlimit_set(0, true, true, false);
-+ hardware_threadlimit_set(0);
- return;
- }
-diff --git a/src/xz/hardware.h b/src/xz/hardware.h
-index 4fae618..ad526f2 100644
---- a/src/xz/hardware.h
-+++ b/src/xz/hardware.h
-@@ -15,11 +15,12 @@
- extern void hardware_init(void);
-
-
--/// Set the maximum number of worker threads.
--extern void hardware_threads_set(uint32_t threadlimit);
-+/// Set custom value for maximum number of coder threads.
-+extern void hardware_threadlimit_set(uint32_t threadlimit);
-
--/// Get the maximum number of worker threads.
--extern uint32_t hardware_threads_get(void);
-+/// Get the maximum number of coder threads. Some additional helper threads
-+/// are allowed on top of this).
-+extern uint32_t hardware_threadlimit_get(void);
-
-
- /// Set the memory usage limit. There are separate limits for compression
-diff --git a/src/xz/private.h b/src/xz/private.h
-index 978f81a..6b01e51 100644
---- a/src/xz/private.h
-+++ b/src/xz/private.h
-@@ -12,8 +12,6 @@
-
- #include "sysdefs.h"
- #include "mythread.h"
--
--#define LZMA_UNSTABLE
- #include "lzma.h"
-
- #include <sys/types.h>
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index f4680f4..0329128 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2011-04-12" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2011-04-11" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
-@@ -907,30 +907,24 @@ Automatic adjusting is always disabled when creating raw streams
- .TP
- \fB\-T\fR \fIthreads\fR, \fB\-\-threads=\fIthreads
- Specify the number of worker threads to use.
--Setting
--.I threads
--to a special value
--.B 0
--makes
--.B xz
--use as many threads as there are CPU cores on the system.
- The actual number of threads can be less than
- .I threads
--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 ""
--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 overriden with the
--.BI \-\-block\-size= size
--option.
-+.B "Multithreaded compression and decompression are not"
-+.B "implemented yet, so this option has no effect for now."
- .IP ""
--.B "It is possible that the details of this option change before"
--.B "the next stable XZ Utils release."
--.B "This may include the meaning of the special value 0."
--.\" FIXME
-+.B "As of writing (2010-09-27), it hasn't been decided"
-+.B "if threads will be used by default on multicore systems"
-+.B "once support for threading has been implemented."
-+.B "Comments are welcome."
-+The complicating factor is that using many threads
-+will increase the memory usage dramatically.
-+Note that if multithreading will be the default,
-+it will probably be done so that single-threaded and
-+multithreaded modes produce the same output,
-+so compression ratio won't be significantly affected
-+if threading will be enabled by default.
- .
- .SS "Custom compressor filter chains"
- A custom filter chain allows specifying
---
-1.7.6
-
diff --git a/debian/patches/abi-version-script b/debian/patches/abi-version-script
deleted file mode 100644
index 2c5a2c4..0000000
--- a/debian/patches/abi-version-script
+++ /dev/null
@@ -1,44 +0,0 @@
-From: Jonathan Nieder <jrnieder@gmail.com>
-Date: Sat, 11 Jun 2011 23:33:43 -0500
-Subject: liblzma: Remove XZ_5.1.1alpha version symbol
-
-Now that the lzma_stream_encoder_mt{,_memusage} symbols are gone on
-this branch, liblzma should stop pretending to satisfy dependencies on
-XZ_5.1.1alpha.
-
-After this change, programs relying on those symbols will error out
-immediately at startup like they are supposed to:
-
- app: liblzma.so.5: version `XZ_5.1.1alpha' not found (required by app)
-
-And your scripts that look for version definition entries with
-readelf -s (like RPM’s find-provides) can tell that this copy of
-liblzma lacks support for multithreaded encoding.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/liblzma/liblzma.map | 8 +-------
- 1 files changed, 1 insertions(+), 7 deletions(-)
-
-diff --git a/src/liblzma/liblzma.map b/src/liblzma/liblzma.map
-index 835eb26..47a7c22 100644
---- a/src/liblzma/liblzma.map
-+++ b/src/liblzma/liblzma.map
-@@ -93,13 +93,7 @@ global:
- lzma_vli_decode;
- lzma_vli_encode;
- lzma_vli_size;
--};
--
--XZ_5.1.1alpha {
--global:
-- lzma_stream_encoder_mt;
-- lzma_stream_encoder_mt_memusage;
-
- local:
- *;
--} XZ_5.0;
-+};
---
-1.7.7
-
diff --git a/debian/patches/configure-liblzma2-compat b/debian/patches/configure-liblzma2-compat
index 46a9233..00d7668 100644
--- a/debian/patches/configure-liblzma2-compat
+++ b/debian/patches/configure-liblzma2-compat
@@ -57,12 +57,12 @@
3 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/configure.ac b/configure.ac
-index cbf92659..eb510fd9 100644
+index 1476c8e2..bfc3ed7e 100644
--- a/configure.ac
+++ b/configure.ac
-@@ -468,10 +468,39 @@ if test "x$enable_threads" = xyes; then
- CFLAGS=$OLD_CFLAGS
+@@ -479,10 +479,39 @@ if test "x$enable_threads" = xyes; then
fi
+ AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
-# As a Debian-specific hack, liblzma uses dlopen() to check if extra
+# As a Debian-specific hack, liblzma can use dlopen() to check if extra
@@ -103,7 +103,7 @@
echo
echo "Initializing Libtool:"
diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
-index e61d940d..3bfdb755 100644
+index f1693a01..7a2c6ea7 100644
--- a/src/liblzma/common/common.c
+++ b/src/liblzma/common/common.c
@@ -143,16 +143,46 @@ lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
@@ -175,10 +175,10 @@
else if (strm->reserved_int1 != 0
|| strm->reserved_int2 != 0
diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
-index 475661d8..4081c2d3 100644
+index de482b38..f2a4552a 100644
--- a/src/liblzma/common/common.h
+++ b/src/liblzma/common/common.h
-@@ -201,9 +201,11 @@ struct lzma_internal_s {
+@@ -217,9 +217,11 @@ struct lzma_internal_s {
/// made (no input consumed and no output produced by next.code).
bool allow_buf_error;
diff --git a/debian/patches/decoder-check-first-0x00 b/debian/patches/decoder-check-first-0x00
deleted file mode 100644
index 442e318..0000000
--- a/debian/patches/decoder-check-first-0x00
+++ /dev/null
@@ -1,69 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Thu, 28 Jun 2012 10:47:49 +0300
-Subject: liblzma: Check that the first byte of range encoded data is 0x00.
-
-It is just to be more pedantic and thus perhaps catch broken
-files slightly earlier.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/liblzma/lzma/lzma_decoder.c | 8 ++++++--
- src/liblzma/rangecoder/range_decoder.h | 12 +++++++++---
- 2 files changed, 15 insertions(+), 5 deletions(-)
-
-diff --git a/src/liblzma/lzma/lzma_decoder.c b/src/liblzma/lzma/lzma_decoder.c
-index 5abbc0d..b8f9317 100644
---- a/src/liblzma/lzma/lzma_decoder.c
-+++ b/src/liblzma/lzma/lzma_decoder.c
-@@ -289,8 +289,12 @@ lzma_decode(lzma_coder *restrict coder, lzma_dict *restrict dictptr,
- // Initialization //
- ////////////////////
-
-- if (!rc_read_init(&coder->rc, in, in_pos, in_size))
-- return LZMA_OK;
-+ {
-+ const lzma_ret ret = rc_read_init(
-+ &coder->rc, in, in_pos, in_size);
-+ if (ret != LZMA_STREAM_END)
-+ return ret;
-+ }
-
- ///////////////
- // Variables //
-diff --git a/src/liblzma/rangecoder/range_decoder.h b/src/liblzma/rangecoder/range_decoder.h
-index fb96180..e0b051f 100644
---- a/src/liblzma/rangecoder/range_decoder.h
-+++ b/src/liblzma/rangecoder/range_decoder.h
-@@ -25,20 +25,26 @@ typedef struct {
-
-
- /// Reads the first five bytes to initialize the range decoder.
--static inline bool
-+static inline lzma_ret
- rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
- size_t *restrict in_pos, size_t in_size)
- {
- while (rc->init_bytes_left > 0) {
- if (*in_pos == in_size)
-- return false;
-+ return LZMA_OK;
-+
-+ // The first byte is always 0x00. It could have been omitted
-+ // in LZMA2 but it wasn't, so one byte is wasted in every
-+ // LZMA2 chunk.
-+ if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00)
-+ return LZMA_DATA_ERROR;
-
- rc->code = (rc->code << 8) | in[*in_pos];
- ++*in_pos;
- --rc->init_bytes_left;
- }
-
-- return true;
-+ return LZMA_STREAM_END;
- }
-
-
---
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/man-date b/debian/patches/man-date
deleted file mode 100644
index f43d3b7..0000000
--- a/debian/patches/man-date
+++ /dev/null
@@ -1,25 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Fri, 22 Jun 2012 14:34:03 +0300
-Subject: xz: Update man page date to match the latest update.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/xz.1 | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index 3ff89f0..cb8cd1e 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2011-04-11" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2012-05-27" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
---
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/man-xz-lvv-minver b/debian/patches/man-xz-lvv-minver
deleted file mode 100644
index 8b2f44d..0000000
--- a/debian/patches/man-xz-lvv-minver
+++ /dev/null
@@ -1,55 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Sun, 1 Jul 2012 18:44:33 +0300
-Subject: xz: Update the man page about the new field in --robot -lvv.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/xz.1 | 18 +++++++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
-diff --git a/src/xz/xz.1 b/src/xz/xz.1
-index cb8cd1e..4da09ba 100644
---- a/src/xz/xz.1
-+++ b/src/xz/xz.1
-@@ -5,7 +5,7 @@
- .\" This file has been put into the public domain.
- .\" You can do whatever you want with this file.
- .\"
--.TH XZ 1 "2012-05-27" "Tukaani" "XZ Utils"
-+.TH XZ 1 "2012-07-01" "Tukaani" "XZ Utils"
- .
- .SH NAME
- xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
-@@ -1889,6 +1889,14 @@ 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
-@@ -1939,6 +1947,14 @@ 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
---
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/patches/series b/debian/patches/series
index 8020937..799661b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,8 +1,3 @@
-abi-threaded-encoder
-abi-version-script
+silent-rules
abi-liblzma2-compat
configure-liblzma2-compat
-man-date
-man-xz-lvv-minver
-xz-lvv-empty-block-minver
-decoder-check-first-0x00
diff --git a/debian/patches/silent-rules b/debian/patches/silent-rules
new file mode 100644
index 0000000..40b2423
--- /dev/null
+++ b/debian/patches/silent-rules
@@ -0,0 +1,38 @@
+From: Jonathan Nieder <jrnieder@gmail.com>
+Date: Tue, 16 Aug 2011 12:07:19 -0500
+Subject: Build: Use AM_SILENT_RULES if requested
+
+So now you can run "./configure --enable-silent-rules && make" to get
+output like this:
+
+| CC liblzma_la-common.lo
+| CC liblzma_la-block_util.lo
+| CC liblzma_la-easy_preset.lo
+[...]
+
+This makes it easier to see what file each batch of compiler warnings
+is associated to. Since on the other hand it makes errors harder to
+reproduce by hand (you have to use "make V=1"), disable it by default.
+
+The implementation uses m4_ifdef to avoid depending on an automake
+version that implements AM_SILENT_RULES (1.11 or greater).
+---
+ configure.ac | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index 0941e8e3..f18f8959 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -455,6 +455,8 @@ AM_PROG_CC_C_O
+ AM_PROG_AS
+ AC_USE_SYSTEM_EXTENSIONS
+
++m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES])
++
+ if test "x$enable_threads" = xyes; then
+ echo
+ echo "Threading support:"
+--
+1.7.10.2
+
diff --git a/debian/patches/xz-lvv-empty-block-minver b/debian/patches/xz-lvv-empty-block-minver
deleted file mode 100644
index 2c658d9..0000000
--- a/debian/patches/xz-lvv-empty-block-minver
+++ /dev/null
@@ -1,38 +0,0 @@
-From: Lasse Collin <lasse.collin@tukaani.org>
-Date: Wed, 4 Jul 2012 19:58:23 +0300
-Subject: xz: Fix the version number printed by xz -lvv.
-
-The decoder bug was fixed in 5.0.2 instead of 5.0.3.
-
-Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
----
- src/xz/list.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/xz/list.c b/src/xz/list.c
-index e71fbe2..a9e0adb 100644
---- a/src/xz/list.c
-+++ b/src/xz/list.c
-@@ -482,7 +482,7 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
- // Determine the minimum XZ Utils version that supports this Block.
- //
- // Currently the only thing that 5.0.0 doesn't support is empty
-- // LZMA2 Block. This bug was fixed in 5.0.3.
-+ // LZMA2 Block. This decoder bug was fixed in 5.0.2.
- {
- size_t i = 0;
- while (filters[i + 1].id != LZMA_VLI_UNKNOWN)
-@@ -490,8 +490,8 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
-
- if (filters[i].id == LZMA_FILTER_LZMA2
- && iter->block.uncompressed_size == 0
-- && xfi->min_version < 50000032U)
-- xfi->min_version = 50000032U;
-+ && xfi->min_version < 50000022U)
-+ xfi->min_version = 50000022U;
- }
-
- // Convert the filter chain to human readable form.
---
-1.7.9.6 (Apple Git-31.1)
-
diff --git a/debian/rules b/debian/rules
index fcbf5c2..ad3ae4e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -66,13 +66,13 @@
debian/normal-build/Makefile debian/normal-build/Doxyfile: $(configure_input)
dh_auto_configure --builddirectory debian/normal-build -- \
- --disable-threads --disable-static \
+ --disable-static \
$(opt_optimize) $(opt_quiet) \
--disable-xzdec --disable-lzmadec
debian/static-build/Makefile: $(configure_input)
dh_auto_configure --builddirectory debian/static-build -- \
- --disable-threads --disable-shared \
+ --disable-shared \
--enable-liblzma2-compat \
$(opt_optimize) $(opt_quiet) \
--disable-lzmainfo --disable-scripts \
@@ -124,7 +124,7 @@
endif
ifneq (,$(filter quiet,$(DEB_BUILD_OPTIONS)))
- opt_quiet = --quiet
+ opt_quiet = --quiet --enable-silent-rules
MAKEFLAGS += --quiet
endif
diff --git a/debian/symbols b/debian/symbols
index ae398c9..9e13a71 100644
--- a/debian/symbols
+++ b/debian/symbols
@@ -1,6 +1,8 @@
liblzma.so.5 liblzma5 #MINVER#
+| liblzma5 (>= 5.1.1alpha+20120614-exp), liblzma5 (<< 5.1.1alpha+20120614-.)
* Build-Depends-Package: liblzma-dev
(symver)XZ_5.0 5.1.1alpha+20110809
+ (symver)XZ_5.1.1alpha 5.1.1alpha+20120614-exp1~ 1
lzma_code@XZ_5.0 5.1.1alpha+20120614
lzma_raw_buffer_decode@XZ_5.0 5.1.1alpha+20120614
lzma_raw_buffer_encode@XZ_5.0 5.1.1alpha+20120614
diff --git a/debian/xz-utils.README.Debian b/debian/xz-utils.README.Debian
index e1c7b97..8bda9f7 100644
--- a/debian/xz-utils.README.Debian
+++ b/debian/xz-utils.README.Debian
@@ -18,44 +18,23 @@
Differences from standard XZ Utils
----------------------------------
-XZ Utils 5.1.y has some experimental features which are disabled in
-Debian to allow interfaces to evolve. Debian liblzma is also modified
-to avoid breakage when the same process loads liblzma2 from Debian 6.0
-(squeeze) and liblzma5.
+The Debian package modifies liblzma to produce a more readable build
+log and to avoid breakage when a binary links indirectly to liblzma
+from Debian 6.0 (squeeze) and 7.0 (wheezy) at the same time.
-abi-threaded-encoder
- Disable threaded compression in liblzma and xz.
+Patches applied:
-abi-version-script
- liblzma: Do not pretend to satisfy dependencies on XZ_5.1.1alpha.
+ silent-rules:
+ build: Use AM_SILENT_RULES if requested.
-abi-liblzma2-compat, configure-liblzma2-compat
- Do not check reserved fields past the historical end of the
- lzma_stream structure if liblzma.so.2 is loaded in the same
- process image. Likewise when linked statically.
- (See bug #649522.)
+ xz-block-list:
+ xz: Remove support for the --block-list option.
-man-date, man-xz-lvv-minver (from upstream)
- Document the "Minimum version required to decompress" field of
- "xz --robot -v -v --list" output.
-
-xz-lvv-empty-block-minver (from upstream)
- Fix the version number printed by "xz -lvv" for files with Blocks
- of zero uncompressed_size: the decoder bug preventing reading such
- files was fixed in xz 5.0.2, not 5.0.3.
-
-decoder-check-first-0x00 (from upstream)
- Check that the first byte of range encoded data is zero to catch
- broken files sooner.
-
-Changes in 5.1.2alpha not applied:
-
- Docs: Language fix to 01_compress_easy.c
- xz: Add incomplete support for --block-list
- INSTALL: Document --enable-symbol-versions
- configure: Add a comment about *-linux tuples for clarity
- TODO: Warn that threads and fork() do not mix well
- Bump the version number and update NEWS for 5.1.2alpha
+ abi-liblzma2-compat, configure-liblzma2-compat:
+ liblzma: Do not check reserved space past the historical end of
+ the lzma_stream structure if liblzma.so.2 is loaded in the same
+ process image. Likewise when building statically.
+ (See bug #649522.)
LZMA Utils compatibility
------------------------
@@ -87,4 +66,4 @@
See the "Memory usage" section of the xz(1) manual page for details.
- -- Jonathan Nieder <jrnieder@gmail.com> Mon, 10 Sep 2012 14:35:27 -0700
+ -- Jonathan Nieder <jrnieder@gmail.com> Sat, 18 Aug 2012 03:18:42 -0700
diff --git a/debug/translation.bash b/debug/translation.bash
deleted file mode 100644
index df4210d..0000000
--- a/debug/translation.bash
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/bin/bash
-
-###############################################################################
-#
-# Script to check output of some translated messages
-#
-# This should be useful for translators to check that the translated strings
-# look good. This doesn't make xz print all possible strings, but it should
-# cover most of the cases where mistakes can easily happen.
-#
-# Give the path and filename of the xz executable as an argument. If no
-# arguments are given, this script uses ../src/xz/xz (relative to the
-# location of this script).
-#
-# You may want to pipe the output of this script to less -S to view the
-# tables printed by xz --list on a 80-column terminal. On the other hand,
-# viewing the other messages may be better without -S.
-#
-###############################################################################
-#
-# Author: Lasse Collin
-#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-#
-###############################################################################
-
-set -e
-
-# If an argument was given, use it to set the location of the xz executable.
-unset XZ
-if [ -n "$1" ]; then
- XZ=$1
- [ "x${XZ:0:1}" != "x/" ] && XZ="$PWD/$XZ"
-fi
-
-# Locate top_srcdir and go there.
-top_srcdir="$(cd -- "$(dirname -- "$0")" && cd .. && pwd)"
-cd -- "$top_srcdir"
-
-# If XZ wasn't already set, use the default location.
-XZ=${XZ-"$PWD/src/xz/xz"}
-if [ "$(type -t "$XZ" || true)" != "file" ]; then
- echo "Give the location of the xz executable as an argument" \
- "to this script."
- exit 1
-fi
-XZ=$(type -p -- "$XZ")
-
-# Print the xz version and locale information.
-echo "$XZ --version"
-"$XZ" --version
-echo
-if [ -d .git ] && type git > /dev/null 2>&1; then
- echo "Source code version in $PWD:"
- git describe --abbrev=4
-fi
-echo
-locale
-echo
-
-# Make the test files directory the current directory.
-cd tests/files
-
-# Put xz in PATH so that argv[0] stays short.
-PATH=${XZ%/*}:$PATH
-
-# Some of the test commands are error messages and thus don't
-# return successfully.
-set +e
-
-for CMD in \
- "xz --foobarbaz" \
- "xz --memlimit=123abcd" \
- "xz --memlimit=40MiB -6 /dev/null" \
- "xz --memlimit=0 --info-memory" \
- "xz --memlimit-compress=1234MiB --memlimit-decompress=50MiB --info-memory" \
- "xz --verbose --verbose /dev/null | cat" \
- "xz --lzma2=foobarbaz" \
- "xz --lzma2=foobarbaz=abcd" \
- "xz --lzma2=mf=abcd" \
- "xz --lzma2=preset=foobarbaz" \
- "xz --lzma2=mf=bt4,nice=2" \
- "xz --lzma2=nice=50000" \
- "xz --help" \
- "xz --long-help" \
- "xz --list good-*lzma2*" \
- "xz --list good-1-check*" \
- "xz --list --verbose good-*lzma2*" \
- "xz --list --verbose good-1-check*" \
- "xz --list --verbose --verbose good-*lzma2*" \
- "xz --list --verbose --verbose good-1-check*" \
- "xz --list --verbose --verbose unsupported-check.xz"
-do
- echo "-----------------------------------------------------------"
- echo
- echo "\$ $CMD"
- eval "$CMD"
- echo
-done 2>&1
diff --git a/doc/examples/01_compress_easy.c b/doc/examples/01_compress_easy.c
index f79cade..e6dd2b0 100644
--- a/doc/examples/01_compress_easy.c
+++ b/doc/examples/01_compress_easy.c
@@ -27,7 +27,7 @@
{
fprintf(stderr, "Usage: %s PRESET < INFILE > OUTFILE\n"
"PRESET is a number 0-9 and can optionally be "
- "by `e' to indicate extreme preset\n",
+ "followed by `e' to indicate extreme preset\n",
argv0);
exit(EXIT_FAILURE);
}
diff --git a/macosx/build.sh b/macosx/build.sh
deleted file mode 100755
index d48ee61..0000000
--- a/macosx/build.sh
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/sh
-
-###############################################################################
-# Author: Anders F Björklund <afb@users.sourceforge.net>
-#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-###############################################################################
-
-mkdir -p Root
-mkdir -p Resources
-
-# Abort immediately if something goes wrong.
-set -e
-
-# Clean up if it was already configured.
-[ -f Makefile ] && make distclean
-
-# Build the regular fat program
-
-CC="gcc-4.0" \
-CFLAGS="-O2 -g -arch ppc -arch ppc64 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
-../configure --disable-dependency-tracking --disable-xzdec --disable-lzmadec i686-apple-darwin8
-
-make
-
-make check
-
-make DESTDIR=`pwd`/Root install
-
-make distclean
-
-# Build the size-optimized program
-
-CC="gcc-4.0" \
-CFLAGS="-Os -g -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
-../configure --disable-dependency-tracking --disable-shared --disable-nls --disable-encoders --enable-small --disable-threads i686-apple-darwin8
-
-make -C src/liblzma
-make -C src/xzdec
-make -C src/xzdec DESTDIR=`pwd`/Root install
-
-cp -a ../extra Root/usr/local/share/doc/xz
-
-make distclean
-
-# Strip debugging symbols and make relocatable
-
-for bin in xz lzmainfo xzdec lzmadec; do
- strip -S Root/usr/local/bin/$bin
- install_name_tool -change /usr/local/lib/liblzma.5.dylib @executable_path/../lib/liblzma.5.dylib Root/usr/local/bin/$bin
-done
-
-for lib in liblzma.5.dylib; do
- strip -S Root/usr/local/lib/$lib
- install_name_tool -id @executable_path/../lib/liblzma.5.dylib Root/usr/local/lib/$lib
-done
-
-strip -S Root/usr/local/lib/liblzma.a
-rm -f Root/usr/local/lib/liblzma.la
-
-# Include pkg-config while making relocatable
-
-sed -e 's|prefix=/usr/local|prefix=${pcfiledir}/../..|' < Root/usr/local/lib/pkgconfig/liblzma.pc > Root/liblzma.pc
-mv Root/liblzma.pc Root/usr/local/lib/pkgconfig/liblzma.pc
-
-# Create tarball, but without the HFS+ attrib
-
-rmdir debug lib po src/liblzma/api src/liblzma src/lzmainfo src/scripts src/xz src/xzdec src tests
-
-( cd Root/usr/local; COPY_EXTENDED_ATTRIBUTES_DISABLE=true COPYFILE_DISABLE=true tar cvjf ../../../XZ.tbz * )
-
-# Include documentation files for package
-
-cp -p ../README Resources/ReadMe.txt
-cp -p ../COPYING Resources/License.txt
-
-# Make an Installer.app package
-
-ID="org.tukaani.xz"
-VERSION=`cd ..; sh build-aux/version.sh`
-PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
-$PACKAGEMAKER -r Root/usr/local -l /usr/local -e Resources -i $ID -n $VERSION -t XZ -o XZ.pkg -g 10.4 --verbose
-
-# Put the package in a disk image
-
-hdiutil create -fs HFS+ -format UDZO -quiet -srcfolder XZ.pkg -ov XZ.dmg
-hdiutil internet-enable -yes -quiet XZ.dmg
-
-echo
-echo "Build completed successfully."
-echo
diff --git a/po/cs.po b/po/cs.po
index a7041ec..f904c92 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -6,7 +6,7 @@
msgstr ""
"Project-Id-Version: xz-utils\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2010-12-03 11:25+0100\n"
+"POT-Creation-Date: 2012-07-04 20:51+0300\n"
"PO-Revision-Date: 2010-12-03 11:32+0100\n"
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
"Language-Team: Czech <diskuze@lists.l10n.cz>\n"
@@ -18,68 +18,86 @@
"X-Poedit-Language: Czech\n"
"X-Poedit-SourceCharset: utf-8\n"
-#: src/xz/args.c:333
+#: src/xz/args.c:62
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:72
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:101
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:401
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Neznámý typ formátu souboru"
-#: src/xz/args.c:356 src/xz/args.c:364
+#: src/xz/args.c:424 src/xz/args.c:432
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Neznámý typ kontroly integrity"
-#: src/xz/args.c:382
+#: src/xz/args.c:464
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"
+msgstr "Spolu s přepínači „--files“ nebo „--files0“ může být zadán pouze jeden soubor"
-#: src/xz/args.c:445
+#: src/xz/args.c:527
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Proměnná prostředí %s obsahuje příliš mnoho argumentů"
-#: src/xz/coder.c:95
+#: src/xz/coder.c:106
msgid "Maximum number of filters is four"
msgstr "Maximální počet filtrů je čtyři"
-#: src/xz/coder.c:108
+#: src/xz/coder.c:119
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:129
+#: src/xz/coder.c:149
msgid "Using a preset in raw mode is discouraged."
msgstr "Použití přednastavení v režimu raw je nevhodné."
-#: src/xz/coder.c:131
+#: src/xz/coder.c:151
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."
+msgstr "Přesné volby u přednastavení se mohou lišit mezi různými verzemi softwaru."
-#: src/xz/coder.c:157
+#: src/xz/coder.c:177
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Formát .lzma podporuje pouze filtr LZMA1"
-#: src/xz/coder.c:165
+#: src/xz/coder.c:185
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 nelze použít s formátem .xz"
-#: src/xz/coder.c:182
+#: src/xz/coder.c:204
+#, c-format
+msgid "Using up to %<PRIu32> threads."
+msgstr ""
+
+#: src/xz/coder.c:217
msgid "Unsupported filter chain or filter options"
msgstr "Nepodporovaný omezující filtr nebo volby filtru"
-#: src/xz/coder.c:190
+#: src/xz/coder.c:225
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "Dekomprimace bude vyžadovat %s MiB paměti."
-#: src/xz/coder.c:247
+#: src/xz/coder.c:260
+#, fuzzy, c-format
+msgid "Adjusted 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:314
#, 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"
+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"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
@@ -91,119 +109,118 @@
#. 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:137
+#: src/xz/file_io.c:136
#, 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:144 src/xz/file_io.c:590
+#: src/xz/file_io.c:143 src/xz/file_io.c:635
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s: Nelze odstranit: %s"
-#: src/xz/file_io.c:169
+#: src/xz/file_io.c:168
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s: Nelze nastavit vlastníka souboru: %s"
-#: src/xz/file_io.c:175
+#: src/xz/file_io.c:174
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s: Nelze nastavit skupinu souboru: %s"
-#: src/xz/file_io.c:194
+#: src/xz/file_io.c:193
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s: Nelze nastavit oprávnění souboru: %s"
-#: src/xz/file_io.c:337 src/xz/file_io.c:420
+#: src/xz/file_io.c:340 src/xz/file_io.c:423
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s: Jedná se o symbolický odkaz, vynechává se"
-#: src/xz/file_io.c:455
+#: src/xz/file_io.c:468
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s: Jedná se o složku, vynechává se"
-#: src/xz/file_io.c:462
+#: src/xz/file_io.c:474
#, 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:479
+#: src/xz/file_io.c:491
#, 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:486
+#: src/xz/file_io.c:498
#, 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:493
+#: src/xz/file_io.c:505
#, 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:714
+#: src/xz/file_io.c:761
#, 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:726
+#: src/xz/file_io.c:773
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s: Selhalo zavření souboru: %s"
-#: src/xz/file_io.c:762 src/xz/file_io.c:946
+#: src/xz/file_io.c:809 src/xz/file_io.c:1008
#, 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"
+msgstr "%s: Selhalo nastavení pozice při pokusu o vytvoření souboru řídké matice: %s"
-#: src/xz/file_io.c:821
+#: src/xz/file_io.c:883
#, c-format
msgid "%s: Read error: %s"
msgstr "%s: Chyba čtení: %s"
-#: src/xz/file_io.c:844
+#: src/xz/file_io.c:906
#, 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:854
+#: src/xz/file_io.c:916
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s: Neočekávaný konec souboru"
-#: src/xz/file_io.c:904
+#: src/xz/file_io.c:966
#, c-format
msgid "%s: Write error: %s"
msgstr "%s: Chyba zápisu: %s"
-#: src/xz/hardware.c:100
+#: src/xz/hardware.c:101
msgid "Disabled"
msgstr "Vypnuto"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
-#: src/xz/hardware.c:119
+#: src/xz/hardware.c:120
msgid "Total amount of physical memory (RAM): "
msgstr "Celkové množství fyzické paměti (RAM): "
-#: src/xz/hardware.c:121
+#: src/xz/hardware.c:122
msgid "Memory usage limit for compression: "
msgstr "Omezení použitelné paměti pro komprimaci: "
-#: src/xz/hardware.c:123
+#: src/xz/hardware.c:124
msgid "Memory usage limit for decompression: "
msgstr "Omezení použitelné paměti pro dekomprimaci:"
#. TRANSLATORS: Indicates that there is no integrity check.
#. This string is used in tables, so the width must not
#. exceed ten columns with a fixed-width font.
-#: src/xz/list.c:62
+#: src/xz/list.c:65
msgid "None"
msgstr "žádná"
@@ -212,60 +229,60 @@
#. strings are used in tables, so the width must not exceed ten
#. columns with a fixed-width font. It's OK to omit the dash if
#. you need space for one extra letter, but don't use spaces.
-#: src/xz/list.c:69
+#: src/xz/list.c:72
msgid "Unknown-2"
msgstr "neznámá-2"
-#: src/xz/list.c:70
+#: src/xz/list.c:73
msgid "Unknown-3"
msgstr "neznámá-3"
-#: src/xz/list.c:72
+#: src/xz/list.c:75
msgid "Unknown-5"
msgstr "neznámá-5"
-#: src/xz/list.c:73
+#: src/xz/list.c:76
msgid "Unknown-6"
msgstr "neznámá-6"
-#: src/xz/list.c:74
+#: src/xz/list.c:77
msgid "Unknown-7"
msgstr "neznámá-7"
-#: src/xz/list.c:75
+#: src/xz/list.c:78
msgid "Unknown-8"
msgstr "neznámá-8"
-#: src/xz/list.c:76
+#: src/xz/list.c:79
msgid "Unknown-9"
msgstr "neznámá-9"
-#: src/xz/list.c:78
+#: src/xz/list.c:81
msgid "Unknown-11"
msgstr "neznámá-11"
-#: src/xz/list.c:79
+#: src/xz/list.c:82
msgid "Unknown-12"
msgstr "neznámá-12"
-#: src/xz/list.c:80
+#: src/xz/list.c:83
msgid "Unknown-13"
msgstr "neznámá-13"
-#: src/xz/list.c:81
+#: src/xz/list.c:84
msgid "Unknown-14"
msgstr "neznámá-14"
-#: src/xz/list.c:82
+#: src/xz/list.c:85
msgid "Unknown-15"
msgstr "neznámá-15"
-#: src/xz/list.c:126
+#: src/xz/list.c:153
#, c-format
msgid "%s: File is empty"
msgstr "%s: Soubor je prázdný"
-#: src/xz/list.c:131
+#: src/xz/list.c:158
#, 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"
@@ -274,41 +291,41 @@
#. 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:612
+#: src/xz/list.c:645
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr "Proud Bloky Komprim Nekomprim Poměr Kontrl Název souboru"
-#: src/xz/list.c:652
+#: src/xz/list.c:685
#, c-format
msgid " Streams: %s\n"
msgstr " Proudů: %s\n"
-#: src/xz/list.c:654
+#: src/xz/list.c:687
#, c-format
msgid " Blocks: %s\n"
msgstr " Bloků: %s\n"
-#: src/xz/list.c:656
+#: src/xz/list.c:689
#, c-format
msgid " Compressed size: %s\n"
msgstr " Komprimovaná velikost: %s\n"
-#: src/xz/list.c:659
+#: src/xz/list.c:692
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Nekomprimovaná velikost: %s\n"
-#: src/xz/list.c:662
+#: src/xz/list.c:695
#, c-format
msgid " Ratio: %s\n"
msgstr " Poměr komprimace: %s\n"
-#: src/xz/list.c:664
+#: src/xz/list.c:697
#, c-format
msgid " Check: %s\n"
msgstr " Typ kontroly: %s\n"
-#: src/xz/list.c:665
+#: src/xz/list.c:698
#, c-format
msgid " Stream padding: %s\n"
msgstr " Zarovnání proudu: %s\n"
@@ -316,28 +333,24 @@
#. TRANSLATORS: The second line is column headings. All except
#. Check are right aligned; Check is left aligned. Test with
#. "xz -lv foo.xz".
-#: src/xz/list.c:693
+#: src/xz/list.c:726
msgid ""
" Streams:\n"
-" Stream Blocks CompOffset UncompOffset CompSize "
-"UncompSize Ratio Check Padding"
+" Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding"
msgstr ""
" Proudy:\n"
-" Proud Bloky KomprPozice NekomprPozice KomprVelikost "
-"NekomprVelikost Poměr Kontrola Zarovnání"
+" Proud Bloky KomprPozice NekomprPozice KomprVelikost NekomprVelikost Poměr Kontrola Zarovnání"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
-#: src/xz/list.c:748
+#: src/xz/list.c:781
#, c-format
msgid ""
" Blocks:\n"
-" Stream Block CompOffset UncompOffset TotalSize "
-"UncompSize Ratio Check"
+" Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check"
msgstr ""
" Bloky:\n"
-" Proud Blok KomprPozice NekomprPozice CelkVelikost "
-"NekomprVelikost Poměr Kontrola"
+" Proud Blok KomprPozice NekomprPozice CelkVelikost NekomprVelikost Poměr Kontrola"
#. TRANSLATORS: These are additional column headings
#. for the most verbose listing mode. CheckVal
@@ -346,32 +359,37 @@
#. are right aligned. %*s is replaced with 0-120
#. spaces to make the CheckVal column wide enough.
#. Test with "xz -lvv foo.xz".
-#: src/xz/list.c:760
+#: src/xz/list.c:793
#, c-format
msgid " CheckVal %*s Header Flags CompSize MemUsage Filters"
msgstr " KontrHod %*s Hlavič Příznaky KomprVel PoužiPam Filtry"
-#: src/xz/list.c:838 src/xz/list.c:1007
+#: src/xz/list.c:871 src/xz/list.c:1046
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Potřebná paměť: %s MiB\n"
-#: src/xz/list.c:840 src/xz/list.c:1009
+#: src/xz/list.c:873 src/xz/list.c:1048
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Velikosti v hlavičkách: %s\n"
-#: src/xz/list.c:841 src/xz/list.c:1010
+#: src/xz/list.c:874 src/xz/list.c:1049
msgid "Yes"
msgstr "Ano"
-#: src/xz/list.c:841 src/xz/list.c:1010
+#: src/xz/list.c:874 src/xz/list.c:1049
msgid "No"
msgstr "Ne"
+#: src/xz/list.c:875 src/xz/list.c:1050
+#, c-format
+msgid " Minimum XZ Utils version: %s\n"
+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:986
+#: src/xz/list.c:1025
#, c-format
msgid "%s file\n"
msgid_plural "%s files\n"
@@ -379,20 +397,20 @@
msgstr[1] "%s soubory\n"
msgstr[2] "%s souborů\n"
-#: src/xz/list.c:999
+#: src/xz/list.c:1038
msgid "Totals:"
msgstr "Celkem:"
-#: src/xz/list.c:1000
+#: src/xz/list.c:1039
#, c-format
msgid " Number of files: %s\n"
msgstr " Počet souborů: %s\n"
-#: src/xz/list.c:1072
+#: src/xz/list.c:1114
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:1078
+#: src/xz/list.c:1120
msgid "--list does not support reading from standard input"
msgstr "--list nepodporuje čtení ze standardního vstupu"
@@ -408,78 +426,83 @@
#: src/xz/main.c:120
#, c-format
-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“?"
+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:174
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:231
-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ů"
+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ů"
-#: src/xz/message.c:792 src/xz/message.c:842
+#. 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:733
+#, c-format
+msgid "%s: "
+msgstr ""
+
+#: src/xz/message.c:796 src/xz/message.c:846
msgid "Internal error (bug)"
msgstr "Interní chyba"
-#: src/xz/message.c:799
+#: src/xz/message.c:803
msgid "Cannot establish signal handlers"
msgstr "Nelze ustanovit ovladač signálu"
-#: src/xz/message.c:808
+#: src/xz/message.c:812
msgid "No integrity check; not verifying file integrity"
msgstr "Žádná kontrola integrity; integrita souboru se nebude ověřovat"
-#: src/xz/message.c:811
+#: src/xz/message.c:815
msgid "Unsupported type of integrity check; not verifying file integrity"
-msgstr ""
-"Nepodporovaný typ kontroly integrity; integrita souboru se nebude ověřovat"
+msgstr "Nepodporovaný typ kontroly integrity; integrita souboru se nebude ověřovat"
-#: src/xz/message.c:818
+#: src/xz/message.c:822
msgid "Memory usage limit reached"
msgstr "Dosaženo omezení použitelné paměti"
-#: src/xz/message.c:821
+#: src/xz/message.c:825
msgid "File format not recognized"
msgstr "Formát souboru nebyl rozpoznán"
-#: src/xz/message.c:824
+#: src/xz/message.c:828
msgid "Unsupported options"
msgstr "Nepodporovaná volba"
-#: src/xz/message.c:827
+#: src/xz/message.c:831
msgid "Compressed data is corrupt"
msgstr "Komprimovaná data jsou poškozená"
-#: src/xz/message.c:830
+#: src/xz/message.c:834
msgid "Unexpected end of input"
msgstr "Neočekávaný konec vstupu"
-#: src/xz/message.c:881
+#: src/xz/message.c:867
+#, fuzzy, c-format
+msgid "%s MiB of memory is required. The limiter is disabled."
+msgstr "Je vyžadováno %s MiB paměti. Limit je %s."
+
+#: src/xz/message.c:895
#, 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:1048
+#: src/xz/message.c:1062
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s: Omezující filtr: %s\n"
-#: src/xz/message.c:1058
+#: src/xz/message.c:1072
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Zkuste „%s --help“ pro více informací"
-#: src/xz/message.c:1084
+#: src/xz/message.c:1098
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
@@ -490,18 +513,15 @@
"Komprimuje nebo dekomprimuje SOUBORy ve formátu xz.\n"
"\n"
-#: src/xz/message.c:1091
-msgid ""
-"Mandatory arguments to long options are mandatory for short options too.\n"
-msgstr ""
-"Povinné argumenty pro dlouhé přepínače jsou povinné rovněž pro krátké "
-"přepínače.\n"
+#: src/xz/message.c:1105
+msgid "Mandatory arguments to long options are mandatory for short options too.\n"
+msgstr "Povinné argumenty pro dlouhé přepínače jsou povinné rovněž pro krátké přepínače.\n"
-#: src/xz/message.c:1095
+#: src/xz/message.c:1109
msgid " Operation mode:\n"
msgstr "Operační režim:\n"
-#: src/xz/message.c:1098
+#: src/xz/message.c:1112
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
@@ -513,7 +533,7 @@
" -t, --test testovat integritu komprimovaného souboru\n"
" -l, --list vypsat informace o souborech .xz"
-#: src/xz/message.c:1104
+#: src/xz/message.c:1118
msgid ""
"\n"
" Operation modifiers:\n"
@@ -521,39 +541,39 @@
"\n"
"Modifikátory operací:\n"
-#: src/xz/message.c:1107
+#: src/xz/message.c:1121
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"
+" -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"
-#: src/xz/message.c:1113
+#: src/xz/message.c:1127
+msgid ""
+" --single-stream decompress only the first stream, and silently\n"
+" ignore possible remaining input data"
+msgstr ""
+
+#: src/xz/message.c:1130
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"
+" 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"
+" --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"
+" --files0[=SOUBOR] stejné jako --files, ale použít k zakončování nulový znak"
-#: src/xz/message.c:1121
+#: src/xz/message.c:1139
msgid ""
"\n"
" Basic file format and compression options:\n"
@@ -561,7 +581,7 @@
"\n"
"Základní přepínače pro formát souboru a komprimaci:\n"
-#: src/xz/message.c:1123
+#: src/xz/message.c:1141
msgid ""
" -F, --format=FMT file format to encode or decode; possible values are\n"
" `auto' (default), `xz', `lzma', and `raw'\n"
@@ -570,76 +590,76 @@
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"
+" -C, --check=KONTROLA typ kontroly integrity: „none“ (používejte s rozmyslem),\n"
" „crc32“, „crc64“ (výchozí) nebo „sha256“"
-#: src/xz/message.c:1130
+#: src/xz/message.c:1148
msgid ""
-" -0 ... -9 compression preset; default is 6; take compressor "
-"*and*\n"
-" decompressor memory usage into account before using "
-"7-9!"
+" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
+" 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"
+" -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"
-#: src/xz/message.c:1134
+#: src/xz/message.c:1152
msgid ""
-" -e, --extreme try to improve compression ratio by using more CPU "
-"time;\n"
+" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" 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"
-#: src/xz/message.c:1139
+#: src/xz/message.c:1158
+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 ""
+
+#: src/xz/message.c:1163
+msgid ""
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"
+msgstr ""
+
+#: src/xz/message.c:1167
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
-" set memory usage limit for compression, "
-"decompression,\n"
+" set memory usage limit for compression, decompression,\n"
" or both; LIMIT is in 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"
+" dekomprimaci nebo obojí; LIMIT je v bajtech, % z paměti\n"
" RAM nebo 0 pro výchozí"
-#: src/xz/message.c:1146
+#: src/xz/message.c:1174
msgid ""
-" --no-adjust if compression settings exceed the memory usage "
-"limit,\n"
-" give an error instead of adjusting the settings "
-"downwards"
+" --no-adjust if compression settings exceed the memory usage limit,\n"
+" give an error instead of adjusting the settings downwards"
msgstr ""
-" --no-adjust pokud nastavení komprimace přesáhne omezení "
-"použitelné\n"
+" --no-adjust pokud nastavení komprimace přesáhne omezení použitelné\n"
" paměti, předat chybu namísto snížení nastavení"
-#: src/xz/message.c:1152
+#: src/xz/message.c:1180
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
msgstr ""
"\n"
-"Vlastní omezující filtr pro komprimaci (alternativa k použití "
-"přednastavených):"
+"Vlastní omezující filtr pro komprimaci (alternativa k použití přednastavených):"
-#: src/xz/message.c:1161
+#: src/xz/message.c:1189
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"
+" --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"
@@ -647,33 +667,24 @@
" 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)"
+" 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"
+" --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"
+" 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í)"
-#: src/xz/message.c:1176
+#: src/xz/message.c:1204
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -695,7 +706,7 @@
" Platné volby pro všechny filtry BCJ:\n"
" start=POČ počáteční posun pro převody (výchozí=0)"
-#: src/xz/message.c:1188
+#: src/xz/message.c:1216
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -704,11 +715,10 @@
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"
+" dist=POČ vzdálenost mezi bajty, které jsou odečítány\n"
" jeden od druhého (1 – 256; 1)"
-#: src/xz/message.c:1196
+#: src/xz/message.c:1224
msgid ""
"\n"
" Other options:\n"
@@ -716,79 +726,71 @@
"\n"
" Ostatní přepínače:\n"
-#: src/xz/message.c:1199
+#: src/xz/message.c:1227
msgid ""
-" -q, --quiet suppress warnings; specify twice to suppress errors "
-"too\n"
+" -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"
+" -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ší"
-#: src/xz/message.c:1204
+#: src/xz/message.c:1232
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn způsobí, že varování neovlivní stav ukončení"
-#: src/xz/message.c:1206
-msgid ""
-" --robot use machine-parsable messages (useful for scripts)"
+#: src/xz/message.c:1234
+msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr ""
" --robot použít strojově analyzovatelné zprávy (užitečné pro\n"
" skripty)"
-#: src/xz/message.c:1209
+#: src/xz/message.c:1237
msgid ""
-" --info-memory display the total amount of RAM and the currently "
-"active\n"
+" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
msgstr ""
-" --info-memory zobrazit celkové množství paměti RAM a současné "
-"aktivní\n"
+" --info-memory zobrazit celkové množství paměti RAM a současné aktivní\n"
" omezení použitelné paměti a skončit"
-#: src/xz/message.c:1212
+#: src/xz/message.c:1240
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, --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"
-#: src/xz/message.c:1216
+#: src/xz/message.c:1244
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)"
+" -H, --long-help zobrazit úplnou nápovědu (vypíše i pokročilé přepínače)"
-#: src/xz/message.c:1221
+#: src/xz/message.c:1249
msgid " -V, --version display the version number and exit"
msgstr " -V, --version zobrazit číslo verze a skončit"
-#: src/xz/message.c:1223
+#: src/xz/message.c:1251
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
msgstr ""
"\n"
-"Pokud SOUBOR není zadán nebo pokud je -, bude se číst ze standardního "
-"vstupu.\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
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
-#: src/xz/message.c:1229
+#: src/xz/message.c:1257
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr "Chyby hlaste na <%s> (v angličtině nebo finštině).\n"
-#: src/xz/message.c:1231
+#: src/xz/message.c:1259
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Domovská stránka %s: <%s>\n"
@@ -822,25 +824,22 @@
msgid "The selected match finder requires at least nice=%<PRIu32>"
msgstr "Vybraný vyhledávač shod vyžaduje minimálně nice=%<PRIu32>"
-#: src/xz/suffix.c:79 src/xz/suffix.c:164
+#: src/xz/suffix.c:133 src/xz/suffix.c:258
#, c-format
-msgid ""
-"%s: 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"
+msgid "%s: 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/suffix.c:99
+#: src/xz/suffix.c:164
#, 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:154
+#: src/xz/suffix.c:185
#, c-format
msgid "%s: File already has `%s' suffix, skipping"
msgstr "%s: Soubor již má příponu „%s“, vynechává se"
-#: src/xz/suffix.c:205
+#: src/xz/suffix.c:393
#, c-format
msgid "%s: Invalid filename suffix"
msgstr "%s: Neplatná přípona názvu souboru"
@@ -857,9 +856,7 @@
#: src/xz/util.c:105
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)."
+msgstr "Platné jednotky s předponami jsou „KiB“ (2^10 B), „MiB“ (2^20 B) a „GiB“ (2^30 B)."
#: src/xz/util.c:122
#, c-format
@@ -893,49 +890,37 @@
#~ msgstr "%s MiB (%s bajtů)\n"
#~ msgid ""
-#~ " -e, --extreme use more CPU time when encoding to increase "
-#~ "compression\n"
+#~ " -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"
+#~ " -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"
+#~ " -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"
+#~ " -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"
+#~ " --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)"
+#~ " rle=NUM run-length encoder chunk size (0-256; 0)"
#~ msgstr ""
#~ "\n"
-#~ " --subblock[=VOLBY] Subblokový filtr; platné VOLBY (platné hodnoty; "
-#~ "výchozí):\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)"
+#~ " 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"
+#~ "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"
+#~ "Na tomto systému a s tímto nastavením použije tento program maximum ze zhruba\n"
#~ "%s MiB RAM a "
#~ msgid ""
diff --git a/po/de.po b/po/de.po
index 4cf5297..d808f51 100644
--- a/po/de.po
+++ b/po/de.po
@@ -6,91 +6,96 @@
msgstr ""
"Project-Id-Version: XZ Utils 4.999.9beta\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-29 21:55+0200\n"
+"POT-Creation-Date: 2012-07-04 20:51+0300\n"
"PO-Revision-Date: 2010-09-07 20:27+0200\n"
"Last-Translator: <maan@systemlinux.org>\n"
"Language-Team: German\n"
+"Language: \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"
-#: src/xz/args.c:338
+#: src/xz/args.c:62
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:72
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:101
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:401
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Unbekanntes file format"
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:424 src/xz/args.c:432
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Integritäts-Check Typ nicht unterstützt"
-#: src/xz/args.c:396
+#: src/xz/args.c:464
msgid "Only one file can be specified with `--files' or `--files0'."
-msgstr ""
-"Nur ein file kann als Argument für --files oder --files0 angegeben werden."
+msgstr "Nur ein file kann als Argument für --files oder --files0 angegeben werden."
-#: src/xz/args.c:459
+#: src/xz/args.c:527
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Die Umgebungsvariable %s enthält zu viele Argumente"
-#: src/xz/coder.c:105
+#: src/xz/coder.c:106
msgid "Maximum number of filters is four"
msgstr "Maximal vier Filter möglich"
-#: src/xz/coder.c:118
+#: src/xz/coder.c:119
msgid "Memory usage limit is too low for the given filter setup."
-msgstr ""
-"Das Speicher Limit ist zu niedrig für die gegebene Filter Konfiguration."
+msgstr "Das Speicher Limit ist zu niedrig für die gegebene Filter Konfiguration."
-#: src/xz/coder.c:148
+#: src/xz/coder.c:149
msgid "Using a preset in raw mode is discouraged."
msgstr "Verwendung der Voreinstellung im raw Modus wird nicht empfohlen."
-#: src/xz/coder.c:150
+#: src/xz/coder.c:151
msgid "The exact options of the presets may vary between software versions."
-msgstr ""
-"Die genauen Optionen der Voreinstellung können zwischen Software Versionen "
-"variieren."
+msgstr "Die genauen Optionen der Voreinstellung können zwischen Software Versionen variieren."
-#: src/xz/coder.c:176
+#: src/xz/coder.c:177
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Das .lzma Format unterstützt nur den LZMA1 Filter"
-#: src/xz/coder.c:184
+#: src/xz/coder.c:185
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 kann nicht mit dem .xz Format verwendet werden"
-#: src/xz/coder.c:203
+#: src/xz/coder.c:204
+#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Benutze bis zu %<PRIu32> Threads."
-#: src/xz/coder.c:216
+#: src/xz/coder.c:217
msgid "Unsupported filter chain or filter options"
msgstr "Optionen nicht unterstützt"
-#: src/xz/coder.c:224
+#: src/xz/coder.c:225
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "Dekompression wird %s MiB Speicher brauchen."
-#: src/xz/coder.c:259
-msgid ""
-"Adjusted the number of threads from %s to %s to not exceed the memory usage "
-"limit of %s MiB"
-msgstr ""
-"Passte die Anzahl Threads von %s auf %s an um nicht das Speicher "
-"Nutzungslimit von %s MiB zu übersteigen"
-
-#: src/xz/coder.c:313
+#: src/xz/coder.c:260
#, 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 ""
-"Passte LZMA%c Wörterbuch Größe von %s MiB to %s MiB an, um nicht das "
-"Speicher Nutzungslimit von %s MiB zu übersteigen"
+msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
+msgstr "Passte die Anzahl Threads von %s auf %s an um nicht das Speicher Nutzungslimit von %s MiB zu übersteigen"
+
+#: src/xz/coder.c:314
+#, 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 "Passte LZMA%c Wörterbuch Größe von %s MiB to %s MiB an, um nicht das Speicher Nutzungslimit von %s MiB zu übersteigen"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
@@ -105,8 +110,7 @@
#: src/xz/file_io.c:136
#, c-format
msgid "%s: File seems to have been moved, not removing"
-msgstr ""
-"%s: Datei scheint umbenannt worden zu sein, daher wird sie nicht gelöscht"
+msgstr "%s: Datei scheint umbenannt worden zu sein, daher wird sie nicht gelöscht"
#: src/xz/file_io.c:143 src/xz/file_io.c:635
#, c-format
@@ -161,8 +165,7 @@
#: src/xz/file_io.c:761
#, c-format
msgid "Error restoring the O_APPEND flag to standard output: %s"
-msgstr ""
-"Fehler beim Wiederherstellen des O_APPEND flags bei Standard Output: %s"
+msgstr "Fehler beim Wiederherstellen des O_APPEND flags bei Standard Output: %s"
#: src/xz/file_io.c:773
#, c-format
@@ -172,8 +175,7 @@
#: src/xz/file_io.c:809 src/xz/file_io.c:1008
#, c-format
msgid "%s: Seeking failed when trying to create a sparse file: %s"
-msgstr ""
-"%s: Positionierungsfehler beim Versuch eine sparse Datei zu erzeugen: %s"
+msgstr "%s: Positionierungsfehler beim Versuch eine sparse Datei zu erzeugen: %s"
#: src/xz/file_io.c:883
#, c-format
@@ -332,12 +334,10 @@
#: src/xz/list.c:726
msgid ""
" Streams:\n"
-" Stream Blocks CompOffset UncompOffset CompSize "
-"UncompSize Ratio Check Padding"
+" Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding"
msgstr ""
" Ströme:\n"
-" Strom Blöcke KompOffset UnkompOffset KompGröße "
-"UnkompGröße Verh. Check Auffüllung"
+" Strom Blöcke KompOffset UnkompOffset KompGröße UnkompGröße Verh. Check Auffüllung"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
@@ -345,12 +345,10 @@
#, c-format
msgid ""
" Blocks:\n"
-" Stream Block CompOffset UncompOffset TotalSize "
-"UncompSize Ratio Check"
+" Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check"
msgstr ""
" Blöcke:\n"
-" Strom Block KompOffset UnkompOffset TotalGröße "
-"UnkompGröße Verh. Check"
+" Strom Block KompOffset UnkompOffset TotalGröße UnkompGröße Verh. Check"
#. TRANSLATORS: These are additional column headings
#. for the most verbose listing mode. CheckVal
@@ -407,8 +405,7 @@
#: src/xz/list.c:1114
msgid "--list works only on .xz files (--format=xz or --format=auto)"
-msgstr ""
-"--list funktioniert nur mit .xz Dateien (--format=xz oder --format=auto)"
+msgstr "--list funktioniert nur mit .xz Dateien (--format=xz oder --format=auto)"
#: src/xz/list.c:1120
msgid "--list does not support reading from standard input"
@@ -426,24 +423,16 @@
#: src/xz/main.c:120
#, c-format
-msgid ""
-"%s: Null character found when reading filenames; maybe you meant to use `--"
-"files0' instead of `--files'?"
-msgstr ""
-"%s: Null Charakter gefunden beim Lesen der Dateinamen; Meinten Sie `--"
-"files0' statt `--files'?"
+msgid "%s: Null character found when reading filenames; maybe you meant to use `--files0' instead of `--files'?"
+msgstr "%s: Null Charakter gefunden beim Lesen der Dateinamen; Meinten Sie `--files0' statt `--files'?"
#: src/xz/main.c:174
msgid "Compression and decompression with --robot are not supported yet."
msgstr "Kompression und Dekompression mit --robot ist noch nicht unterstützt."
#: src/xz/main.c:231
-msgid ""
-"Cannot read data from standard input when reading filenames from standard "
-"input"
-msgstr ""
-"Lesen der Standardeingabe ist nicht möglich, wenn die Dateinamen auch von "
-"der Standardeingabe gelesen werden"
+msgid "Cannot read data from standard input when reading filenames from standard input"
+msgstr "Lesen der Standardeingabe ist nicht möglich, wenn die Dateinamen auch von der Standardeingabe gelesen werden"
#. TRANSLATORS: This is the program name in the beginning
#. of the line in messages. Usually it becomes "xz: ".
@@ -468,9 +457,7 @@
#: src/xz/message.c:815
msgid "Unsupported type of integrity check; not verifying file integrity"
-msgstr ""
-"Typ des Integritäts-Checks nicht unterstützt; werde Datei-Integrität nicht "
-"überprüfen"
+msgstr "Typ des Integritäts-Checks nicht unterstützt; werde Datei-Integrität nicht überprüfen"
#: src/xz/message.c:822
msgid "Memory usage limit reached"
@@ -524,8 +511,7 @@
"\n"
#: src/xz/message.c:1105
-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.\n"
msgstr ""
"Obligatorische Argumente für lange Optionen sind auch für kurze Optionen\n"
"zwingend.\n"
@@ -580,8 +566,7 @@
" -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"
+" filenames must be terminated with the newline character\n"
" --files0[=FILE] like --files but use the null character as terminator"
msgstr ""
" --no-sparse erzeuge keine sparse Datei beim Dekomprimieren\n"
@@ -590,8 +575,7 @@
" DATEI nicht angegeben wurde, werden Dateinamen\n"
" von Standard Input gelesen. Dateinamen müssen mit\n"
" einem Zeilenumbruch voneinander getrennt werden\n"
-" --files0=[DATEI] wie --files, aber benutze den Null Charakter als "
-"Trenner"
+" --files0=[DATEI] wie --files, aber benutze den Null Charakter als Trenner"
#: src/xz/message.c:1139
msgid ""
@@ -608,80 +592,79 @@
" -C, --check=CHECK integrity check type: `none' (use with caution),\n"
" `crc32', `crc64' (default), or `sha256'"
msgstr ""
-" -F, --format=FMT Dateiformat zur Kodierung oder Dekodierung; "
-"mögliche\n"
-" Werte sind `auto' (Voreinstellung), `xz', `lzma' "
-"und\n"
+" -F, --format=FMT Dateiformat zur Kodierung oder Dekodierung; mögliche\n"
+" Werte sind `auto' (Voreinstellung), `xz', `lzma' und\n"
" `raw'\n"
-" -C, --check=CHECK Typ des Integritätschecks: `none' (Vorsicht), "
-"`crc32',\n"
+" -C, --check=CHECK Typ des Integritätschecks: `none' (Vorsicht), `crc32',\n"
" `crc64' (Voreinstellung), oder `sha256'"
#: src/xz/message.c:1148
msgid ""
-" -0 ... -9 compression preset; default is 6; take compressor "
-"*and*\n"
-" decompressor memory usage into account before using 7-"
-"9!"
+" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
+" decompressor memory usage into account before using 7-9!"
msgstr ""
-" -0 .. -9 Kompressionseinstellung; Voreinstellung is 6. "
-"Beachten\n"
-" Sie den Speicherverbrauch des Komprimieres *und* "
-"des\n"
+" -0 .. -9 Kompressionseinstellung; Voreinstellung is 6. Beachten\n"
+" Sie den Speicherverbrauch des Komprimieres *und* des\n"
" Dekomprimierers, wenn Sie 7-9 benutzen!"
#: src/xz/message.c:1152
msgid ""
-" -e, --extreme try to improve compression ratio by using more CPU "
-"time;\n"
+" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" does not affect decompressor memory requirements"
msgstr ""
-" -e, --extreme Versuche durch stärkere CPU Nutzung das "
-"Kompressions-\n"
+" -e, --extreme Versuche durch stärkere CPU Nutzung das Kompressions-\n"
" verhältnis zu verbessern. Das beeinflusst nicht den\n"
" Speicherbedarf des Dekomprimierers."
-#: src/xz/message.c:1157
+#: src/xz/message.c:1158
+#, fuzzy
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
-" after every SIZE Eingabe Bytes; 0=disabled (default)"
+" after every SIZE bytes of input; 0=disabled (default)"
msgstr ""
" --block-size=SIZE\n"
" beim Komprimieren ins .xz Format, starte einen neuen\n"
" Block nach jeweils SIZE Eingabe Bytes; 0=deaktiviert\n"
" (Grundeinstellung)"
-#: src/xz/message.c:1161
+#: src/xz/message.c:1163
+#, fuzzy
+msgid ""
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"
+msgstr ""
+" --block-size=SIZE\n"
+" beim Komprimieren ins .xz Format, starte einen neuen\n"
+" Block nach jeweils SIZE Eingabe Bytes; 0=deaktiviert\n"
+" (Grundeinstellung)"
+
+#: src/xz/message.c:1167
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
-" set memory usage limit for compression, "
-"decompression,\n"
+" set memory usage limit for compression, decompression,\n"
" or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
msgstr ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT Setze Speicher Nutzungslimit für Kompression,\n"
-" Dekompression, oder beides; LIMIT ist in bytes, % "
-"RAM,\n"
+" Dekompression, oder beides; LIMIT ist in bytes, % RAM,\n"
" oder 0 für Grundeinstellungen."
-#: src/xz/message.c:1168
+#: src/xz/message.c:1174
msgid ""
-" --no-adjust if compression settings exceed the memory usage "
-"limit,\n"
-" give an error instead of adjusting the settings "
-"downwards"
+" --no-adjust if compression settings exceed the memory usage limit,\n"
+" give an error instead of adjusting the settings downwards"
msgstr ""
" --no-adjust Wenn die Kompressionseinstellungen das Speicher\n"
-" Nutzungslimit übersteigen, erzeuge einen Fehler "
-"statt\n"
+" Nutzungslimit übersteigen, erzeuge einen Fehler statt\n"
" die Einstellungen nach unten anzupassen."
-#: src/xz/message.c:1174
+#: src/xz/message.c:1180
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -689,13 +672,11 @@
"\n"
" User-definierte Filter Kette für Kompression (alternativ zu Voreinstellung):"
-#: src/xz/message.c:1183
+#: src/xz/message.c:1189
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"
+" --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"
@@ -703,37 +684,28 @@
" 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)"
+" mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
+" depth=NUM maximum search depth; 0=automatic (default)"
msgstr ""
"\n"
" --lzma1[=OPTIONEN] LZMA1 oder LZMA2; OPTIONEN ist eine durch Kommata\n"
-" --lzma2[=OPTIONEN] getrennte Liste bestehend aus den folgenden "
-"Optionen\n"
+" --lzma2[=OPTIONEN] getrennte Liste bestehend aus den folgenden Optionen\n"
" (zulässige Werte; Voreinstellung):\n"
-" preset=NUM Setze Optionen zurück zu "
-"Voreinstellung\n"
+" preset=NUM Setze Optionen zurück zu Voreinstellung\n"
" (0-9[e])\n"
-" dict=NUM Wörterbuch Größe (4 KiB - 1536 MiB; 8 "
-"MiB)\n"
-" lc=NUM Anzahl der Literal Kontext Bits (0-4; "
-"3)\n"
-" lp=NUM Anzahl der Literal Positionsbits (0-4; "
-"0)\n"
+" dict=NUM Wörterbuch Größe (4 KiB - 1536 MiB; 8 MiB)\n"
+" lc=NUM Anzahl der Literal Kontext Bits (0-4; 3)\n"
+" lp=NUM Anzahl der Literal Positionsbits (0-4; 0)\n"
" pb=NUM Anzahl der Positionsbits (0-4; 2)\n"
-" mode=MODUS Kompressionsmodus (fast, normal; "
-"normal)\n"
+" mode=MODUS Kompressionsmodus (fast, normal; normal)\n"
" nice=NUM Nice-Länge eines Treffers (2-273; 64)\n"
" mf=NAME Algorithmus zum Auffinden von\n"
-" Übereinstimmungen (hc3, hc4, bt2, bt3, "
-"bt4;\n"
+" Übereinstimmungen (hc3, hc4, bt2, bt3, bt4;\n"
" bt4)\n"
" depth=NUM Maximale Suchtiefe; 0=automatisch\n"
" (Voreinstellung)"
-#: src/xz/message.c:1198
+#: src/xz/message.c:1204
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -756,7 +728,7 @@
" start=NUM Start-Offset für Konversion\n"
" (Voreinstellung=0)"
-#: src/xz/message.c:1210
+#: src/xz/message.c:1216
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -766,11 +738,10 @@
"\n"
" --delta[=OPTIONEN] Delta Filter; zulässige Optionen (gültige Werte;\n"
" Voreinstellung):\n"
-" dist=NUM Abstand zwischen den Bytes, die "
-"voneinander\n"
+" dist=NUM Abstand zwischen den Bytes, die voneinander\n"
" subtrahiert werden (1-256; 1)"
-#: src/xz/message.c:1218
+#: src/xz/message.c:1224
msgid ""
"\n"
" Other options:\n"
@@ -778,37 +749,33 @@
"\n"
" Andere Optionen:\n"
-#: src/xz/message.c:1221
+#: src/xz/message.c:1227
msgid ""
-" -q, --quiet suppress warnings; specify twice to suppress errors "
-"too\n"
+" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
msgstr ""
" -q, --quiet unterdrücke Warnungen; benutze diese Option zweimal\n"
" um auch Fehlermeldungen zu unterdrücken\n"
-" -v, --verbose sei gesprächig; benutze diese Option zweimal um "
-"noch\n"
+" -v, --verbose sei gesprächig; benutze diese Option zweimal um noch\n"
" gesprächiger zu sein"
-#: src/xz/message.c:1226
+#: src/xz/message.c:1232
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn Warnungen verändern nicht den exit status"
-#: src/xz/message.c:1228
-msgid ""
-" --robot use machine-parsable messages (useful for scripts)"
+#: src/xz/message.c:1234
+msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr ""
" --robot benutze Maschinen-lesbare Meldungen (nützlich für\n"
" Skripte)"
-#: src/xz/message.c:1231
+#: src/xz/message.c:1237
msgid ""
-" --info-memory display the total amount of RAM and the currently "
-"active\n"
+" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
msgstr " --info-memory zeige Speicherlimit an und terminiere"
-#: src/xz/message.c:1234
+#: src/xz/message.c:1240
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -817,21 +784,20 @@
" Optionen)\n"
" -H, --long-help zeige diese lange Hilfe an und terminiere"
-#: src/xz/message.c:1238
+#: src/xz/message.c:1244
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 zeige diese kurze Hilfe an und terminiere\n"
-" -H, --long-help zeige die lange Hilfe an (zeigt auch "
-"fortgeschrittene\n"
+" -H, --long-help zeige die lange Hilfe an (zeigt auch fortgeschrittene\n"
" Optionen an)"
-#: src/xz/message.c:1243
+#: src/xz/message.c:1249
msgid " -V, --version display the version number and exit"
msgstr " -V, --version zeige Versionsnummer an und terminiere"
-#: src/xz/message.c:1245
+#: src/xz/message.c:1251
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -844,15 +810,14 @@
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1257
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
"Melde Bugs an <%s> (in englisch oder finnisch).\n"
-"Melde Übersetzungsfehler an <maan@systemlinux.org> (in englisch oder "
-"deutsch).\n"
+"Melde Übersetzungsfehler an <maan@systemlinux.org> (in englisch oder deutsch).\n"
-#: src/xz/message.c:1253
+#: src/xz/message.c:1259
#, c-format
msgid "%s home page: <%s>\n"
msgstr "%s Homepage: <%s>\n"
@@ -860,9 +825,7 @@
#: src/xz/options.c:86
#, c-format
msgid "%s: Options must be `name=value' pairs separated with commas"
-msgstr ""
-"%s: Optionen müssen in der Form `Name=Wert` gegeben werden, getrennt durch "
-"Kommata"
+msgstr "%s: Optionen müssen in der Form `Name=Wert` gegeben werden, getrennt durch Kommata"
#: src/xz/options.c:93
#, c-format
@@ -886,17 +849,12 @@
#: src/xz/options.c:359
#, c-format
msgid "The selected match finder requires at least nice=%<PRIu32>"
-msgstr ""
-"Der ausgewählte Algorithmus zum Auffinden von Übereinstimmungen braucht "
-"mindestens nice=%<PRIu32>"
+msgstr "Der ausgewählte Algorithmus zum Auffinden von Übereinstimmungen braucht mindestens nice=%<PRIu32>"
#: src/xz/suffix.c:133 src/xz/suffix.c:258
#, c-format
-msgid ""
-"%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
-msgstr ""
-"%s: Mit --format=raw ist --sufix=.SUF notwendig, falls nicht nach stdout "
-"geschrieben wird"
+msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
+msgstr "%s: Mit --format=raw ist --sufix=.SUF notwendig, falls nicht nach stdout geschrieben wird"
#: src/xz/suffix.c:164
#, c-format
diff --git a/po/fr.po b/po/fr.po
index a21aa85..5ef555d 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -6,7 +6,7 @@
msgstr ""
"Project-Id-Version: xz-utils\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-30 20:40+0200\n"
+"POT-Creation-Date: 2012-07-04 20:51+0300\n"
"PO-Revision-Date: 2010-09-24 21;12+0200\n"
"Last-Translator: Adrien Nader <camaradetux@gmail.com>\n"
"Language-Team: None\n"
@@ -16,69 +16,83 @@
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n"
-#: src/xz/args.c:338
+#: src/xz/args.c:62
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:72
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:101
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:401
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s : Format de fichier inconnu"
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:424 src/xz/args.c:432
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s : Type de vérification d'intégrité inconnu"
-#: src/xz/args.c:396
+#: src/xz/args.c:464
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Un seul fichier peut être spécifié avec `--files' ou `--files0'."
-#: src/xz/args.c:459
+#: src/xz/args.c:527
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "La variable d'environnement %s contient trop d'arguments"
-#: src/xz/coder.c:105
+#: src/xz/coder.c:106
msgid "Maximum number of filters is four"
msgstr "Le nombre maximal de filtres est quatre"
-#: src/xz/coder.c:118
+#: src/xz/coder.c:119
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:148
+#: src/xz/coder.c:149
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:150
+#: src/xz/coder.c:151
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:176
+#: src/xz/coder.c:177
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:184
+#: src/xz/coder.c:185
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:203
+#: src/xz/coder.c:204
#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Jusqu'à %<PRIu32> threads seront utilisés."
-#: src/xz/coder.c:216
+#: src/xz/coder.c:217
msgid "Unsupported filter chain or filter options"
msgstr "Enchaînement ou options de filtres non pris en charge"
-#: src/xz/coder.c:224
+#: src/xz/coder.c:225
#, 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:259
+#: src/xz/coder.c:260
#, c-format
msgid "Adjusted 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:313
+#: src/xz/coder.c:314
#, 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"
@@ -600,7 +614,7 @@
" de temps processeur sans affecter les besoins mémoire du\n"
" décompresseur"
-#: src/xz/message.c:1157
+#: src/xz/message.c:1158
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
@@ -610,7 +624,18 @@
" pour une compression au format .xz, entamer un nouveau\n"
" bloc après SIZE octets d'entrée ; 0=désactivé (par défaut)"
-#: src/xz/message.c:1161
+#: src/xz/message.c:1163
+#, fuzzy
+msgid ""
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"
+msgstr ""
+" --block-size=SIZE\n"
+" pour une compression au format .xz, entamer un nouveau\n"
+" bloc après SIZE octets d'entrée ; 0=désactivé (par défaut)"
+
+#: src/xz/message.c:1167
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
@@ -626,7 +651,7 @@
" décompression ou les deux ; LIMIT est en octets, % de\n"
" RAM, ou 0 pour les valeurs par défaut"
-#: src/xz/message.c:1168
+#: src/xz/message.c:1174
msgid ""
" --no-adjust if compression settings exceed the memory usage limit,\n"
" give an error instead of adjusting the settings downwards"
@@ -635,7 +660,7 @@
" d'utilisation mémoire, renvoyer une erreur plutôt que de\n"
" diminuer les réglages"
-#: src/xz/message.c:1174
+#: src/xz/message.c:1180
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -643,7 +668,7 @@
"\n"
" Enchaînement de filtres de compression personnalisé (au lieu des préréglages) :"
-#: src/xz/message.c:1183
+#: src/xz/message.c:1189
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -672,7 +697,7 @@
" depth=NUM profondeur de recherche maximale ;\n"
" 0=automatique (par défaut)"
-#: src/xz/message.c:1198
+#: src/xz/message.c:1204
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -694,7 +719,7 @@
" OPTS valides pour tous les filtres BCJ :\n"
" start=NUM start offset for conversions (default=0)"
-#: src/xz/message.c:1210
+#: src/xz/message.c:1216
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -706,7 +731,7 @@
" dist=NUM distance entre les octets soustraits\n"
" les uns aux autres (1-256 ; 1)"
-#: src/xz/message.c:1218
+#: src/xz/message.c:1224
msgid ""
"\n"
" Other options:\n"
@@ -714,7 +739,7 @@
"\n"
" Autres options :\n"
-#: src/xz/message.c:1221
+#: src/xz/message.c:1227
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
@@ -723,17 +748,17 @@
" aussi supprimer les erreur\n"
" -v, --verbose être bavard ; spécifier deux fois pour l'être davantage"
-#: src/xz/message.c:1226
+#: src/xz/message.c:1232
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn les avertissements ne modifient pas le code de sortie"
-#: src/xz/message.c:1228
+#: src/xz/message.c:1234
msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr ""
" --robot utiliser des messages lisibles par un programme\n"
" (utile pour les scripts)"
-#: src/xz/message.c:1231
+#: src/xz/message.c:1237
msgid ""
" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
@@ -741,7 +766,7 @@
" --info-memory affiche la quantité totale de RAM et la limite actuelle\n"
" en mémoire puis quitte"
-#: src/xz/message.c:1234
+#: src/xz/message.c:1240
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -749,7 +774,7 @@
" -h, --help affiche l'aide courte (ne liste que les options de base)\n"
" -H, --long-help affiche l'aide longue (ceci) puis quitte"
-#: src/xz/message.c:1238
+#: src/xz/message.c:1244
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
@@ -757,11 +782,11 @@
" -h, --help affiche l'aide courte (ceci) puis quitte\n"
" -H, --long-help affiche l'aide longue (liste aussi les options avancées)"
-#: src/xz/message.c:1243
+#: src/xz/message.c:1249
msgid " -V, --version display the version number and exit"
msgstr " -V, --version affiche le numéro de version puis quitte"
-#: src/xz/message.c:1245
+#: src/xz/message.c:1251
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -773,14 +798,14 @@
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1257
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
"Signaler les bogues à <%s> (en anglais ou en finlandais).\n"
"Signaler les bogues de traduction à <camaradetux@gmail.com>.\n"
-#: src/xz/message.c:1253
+#: src/xz/message.c:1259
#, c-format
msgid "%s home page: <%s>\n"
msgstr "%s page du projet : <%s>\n"
diff --git a/po/it.po b/po/it.po
index b9986f3..42e45d1 100644
--- a/po/it.po
+++ b/po/it.po
@@ -7,8 +7,8 @@
msgid ""
msgstr ""
"Project-Id-Version: xz-utils\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-05-27 11:59+0200\n"
+"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
+"POT-Creation-Date: 2012-07-04 20:51+0300\n"
"PO-Revision-Date: 2011-05-27 11:59+0200\n"
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
@@ -20,86 +20,86 @@
"X-Generator: Launchpad (build Unknown)\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ../src/xz/args.c:338
+#: src/xz/args.c:62
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:72
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:101
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:401
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: tipo di formato del file sconosciuto"
-#: ../src/xz/args.c:361 ../src/xz/args.c:369
+#: src/xz/args.c:424 src/xz/args.c:432
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: tipo di controllo integrità non supportato"
-#: ../src/xz/args.c:396
+#: src/xz/args.c:464
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Solo un file può essere specificato con \"--files\" o \"--files0\"."
-#: ../src/xz/args.c:459
+#: src/xz/args.c:527
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "La variabile d'ambiente %s contiene troppi argomenti"
-#: ../src/xz/coder.c:105
+#: src/xz/coder.c:106
msgid "Maximum number of filters is four"
msgstr "Il numero massimo di filtri è quattro"
-#: ../src/xz/coder.c:118
+#: src/xz/coder.c:119
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."
+msgstr "Il limite dell'uso della memoria è troppo basso per l'impostazione del filtro dato."
-#. The message is shown only if warnings are allowed
-#. but the exit status isn't changed.
-#: ../src/xz/coder.c:148
+#: src/xz/coder.c:149
msgid "Using a preset in raw mode is discouraged."
msgstr "Non è consigliato usare un preset nella modalità raw."
-#: ../src/xz/coder.c:150
+#: src/xz/coder.c:151
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."
+msgstr "Le opzioni esatte per i preset possono variare tra le versioni del software."
-#: ../src/xz/coder.c:176
+#: src/xz/coder.c:177
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Il formato .lzma supporta solo il filtro LZMA1"
-#: ../src/xz/coder.c:184
+#: src/xz/coder.c:185
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 non può essere usato con il formato .xz"
-#: ../src/xz/coder.c:203
+#: src/xz/coder.c:204
#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Vengono usati circa %<PRIu32> thread."
-#: ../src/xz/coder.c:216
+#: src/xz/coder.c:217
msgid "Unsupported filter chain or filter options"
msgstr "Catena di filtri od opzioni del filtro non supportata"
-#: ../src/xz/coder.c:224
+#: src/xz/coder.c:225
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "L'estrazione necessita di %s MiB di memoria."
-#: ../src/xz/coder.c:259
+#: src/xz/coder.c:260
#, c-format
-msgid ""
-"Adjusted the number of threads from %s to %s to not exceed the memory usage "
-"limit of %s MiB"
-msgstr ""
-"Regolato il numero di thread da %s a %s per non eccedere il limite di "
-"utilizzo della memoria di %s MiB"
+msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
+msgstr "Regolato il numero di thread da %s a %s per non eccedere il limite di utilizzo della memoria di %s MiB"
-#. Tell the user that we decreased the dictionary size.
-#: ../src/xz/coder.c:313
+#: src/xz/coder.c:314
#, 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"
+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"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
@@ -111,128 +111,118 @@
#. 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:136
+#: src/xz/file_io.c:136
#, 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:143 ../src/xz/file_io.c:635
+#: src/xz/file_io.c:143 src/xz/file_io.c:635
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s: impossibile rimuovere: %s"
-#: ../src/xz/file_io.c:168
+#: src/xz/file_io.c:168
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s: impossibile impostare il proprietario del file: %s"
-#: ../src/xz/file_io.c:174
+#: src/xz/file_io.c:174
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s: impossibile impostare il gruppo del file: %s"
-#: ../src/xz/file_io.c:193
+#: src/xz/file_io.c:193
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s: impossibile impostare i permessi del file: %s"
-#: ../src/xz/file_io.c:340 ../src/xz/file_io.c:423
+#: src/xz/file_io.c:340 src/xz/file_io.c:423
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s: è un collegamento simbolico, viene saltato"
-#: ../src/xz/file_io.c:468
+#: src/xz/file_io.c:468
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s: è una directory, viene saltata"
-#: ../src/xz/file_io.c:474
+#: src/xz/file_io.c:474
#, c-format
msgid "%s: Not a regular file, skipping"
msgstr "%s: non è un file regolare, viene saltato"
-#. gzip rejects setuid and setgid files even
-#. when --force was used. bzip2 doesn't check
-#. for them, but calls fchown() after fchmod(),
-#. and many systems automatically drop setuid
-#. and setgid bits there.
-#.
-#. We accept setuid and setgid files if
-#. --force was used. We drop these bits
-#. explicitly in io_copy_attr().
-#: ../src/xz/file_io.c:491
+#: src/xz/file_io.c:491
#, 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:498
+#: src/xz/file_io.c:498
#, 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:505
+#: src/xz/file_io.c:505
#, 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:761
+#: src/xz/file_io.c:761
#, 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:773
+#: src/xz/file_io.c:773
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s: chiusura del file non riuscita: %s"
-#: ../src/xz/file_io.c:809 ../src/xz/file_io.c:1008
+#: src/xz/file_io.c:809 src/xz/file_io.c:1008
#, 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"
+msgstr "%s: posizionamento non riuscito nel tentativo di creare un file sparso: %s"
-#: ../src/xz/file_io.c:883
+#: src/xz/file_io.c:883
#, c-format
msgid "%s: Read error: %s"
msgstr "%s: errore di lettura: %s"
-#: ../src/xz/file_io.c:906
+#: src/xz/file_io.c:906
#, c-format
msgid "%s: Error seeking the file: %s"
msgstr "%s: errore nel cercare il file: %s"
-#: ../src/xz/file_io.c:916
+#: src/xz/file_io.c:916
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s: fine del file inaspettata"
-#: ../src/xz/file_io.c:966
+#: src/xz/file_io.c:966
#, c-format
msgid "%s: Write error: %s"
msgstr "%s: errore di scrittura: %s"
-#: ../src/xz/hardware.c:101
+#: src/xz/hardware.c:101
msgid "Disabled"
msgstr "Disabilitato"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
-#: ../src/xz/hardware.c:120
+#: src/xz/hardware.c:120
msgid "Total amount of physical memory (RAM): "
msgstr "Quantità totale di memoria fisica (RAM): "
-#: ../src/xz/hardware.c:122
+#: src/xz/hardware.c:122
msgid "Memory usage limit for compression: "
msgstr "Limite utilizzo memoria per la compressione: "
-#: ../src/xz/hardware.c:124
+#: src/xz/hardware.c:124
msgid "Memory usage limit for decompression: "
msgstr "Limite utilizzo memoria per l'estrazione: "
#. TRANSLATORS: Indicates that there is no integrity check.
#. This string is used in tables, so the width must not
#. exceed ten columns with a fixed-width font.
-#: ../src/xz/list.c:62
+#: src/xz/list.c:65
msgid "None"
msgstr "Nessuno"
@@ -241,60 +231,60 @@
#. strings are used in tables, so the width must not exceed ten
#. columns with a fixed-width font. It's OK to omit the dash if
#. you need space for one extra letter, but don't use spaces.
-#: ../src/xz/list.c:69
+#: src/xz/list.c:72
msgid "Unknown-2"
msgstr "Sconosc2"
-#: ../src/xz/list.c:70
+#: src/xz/list.c:73
msgid "Unknown-3"
msgstr "Sconosc3"
-#: ../src/xz/list.c:72
+#: src/xz/list.c:75
msgid "Unknown-5"
msgstr "Sconosc5"
-#: ../src/xz/list.c:73
+#: src/xz/list.c:76
msgid "Unknown-6"
msgstr "Sconosc6"
-#: ../src/xz/list.c:74
+#: src/xz/list.c:77
msgid "Unknown-7"
msgstr "Sconosc7"
-#: ../src/xz/list.c:75
+#: src/xz/list.c:78
msgid "Unknown-8"
msgstr "Sconosc8"
-#: ../src/xz/list.c:76
+#: src/xz/list.c:79
msgid "Unknown-9"
msgstr "Sconosc9"
-#: ../src/xz/list.c:78
+#: src/xz/list.c:81
msgid "Unknown-11"
msgstr "Sconosc11"
-#: ../src/xz/list.c:79
+#: src/xz/list.c:82
msgid "Unknown-12"
msgstr "Sconosc12"
-#: ../src/xz/list.c:80
+#: src/xz/list.c:83
msgid "Unknown-13"
msgstr "Sconosc13"
-#: ../src/xz/list.c:81
+#: src/xz/list.c:84
msgid "Unknown-14"
msgstr "Sconosc14"
-#: ../src/xz/list.c:82
+#: src/xz/list.c:85
msgid "Unknown-15"
msgstr "Sconosc15"
-#: ../src/xz/list.c:126
+#: src/xz/list.c:153
#, c-format
msgid "%s: File is empty"
msgstr "%s: il file è vuoto"
-#: ../src/xz/list.c:131
+#: src/xz/list.c:158
#, c-format
msgid "%s: Too small to be a valid .xz file"
msgstr "%s: troppo piccolo per essere un file .xz valido"
@@ -303,72 +293,66 @@
#. 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:612
+#: src/xz/list.c:645
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr " Strm Blocc. Compresso Estratto Rapp. Contr Nome file"
-#: ../src/xz/list.c:652
+#: src/xz/list.c:685
#, c-format
msgid " Streams: %s\n"
msgstr " Stream: %s\n"
-#: ../src/xz/list.c:654
+#: src/xz/list.c:687
#, c-format
msgid " Blocks: %s\n"
msgstr " Blocchi: %s\n"
-#: ../src/xz/list.c:656
+#: src/xz/list.c:689
#, c-format
msgid " Compressed size: %s\n"
msgstr " Dim. compresso: %s\n"
-#: ../src/xz/list.c:659
+#: src/xz/list.c:692
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Dim. estratto: %s\n"
-#: ../src/xz/list.c:662
+#: src/xz/list.c:695
#, c-format
msgid " Ratio: %s\n"
msgstr " Rapporto: %s\n"
-#: ../src/xz/list.c:664
+#: src/xz/list.c:697
#, c-format
msgid " Check: %s\n"
msgstr " Controllo: %s\n"
-#: ../src/xz/list.c:665
+#: src/xz/list.c:698
#, c-format
msgid " Stream padding: %s\n"
msgstr " Padding dello stream: %s\n"
-#. Print information about the Streams.
-#.
#. TRANSLATORS: The second line is column headings. All except
#. Check are right aligned; Check is left aligned. Test with
#. "xz -lv foo.xz".
-#: ../src/xz/list.c:693
+#: src/xz/list.c:726
msgid ""
" Streams:\n"
-" Stream Blocks CompOffset UncompOffset CompSize "
-"UncompSize Ratio Check Padding"
+" Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding"
msgstr ""
"Stream:\n"
-" Stream Blocc. Offset comp. Offset estr. Dim. comp. Dim. "
-"estratto Rapp. Contr Padding"
+" Stream Blocc. Offset comp. Offset estr. Dim. comp. Dim. estratto Rapp. Contr Padding"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
-#: ../src/xz/list.c:748
+#: src/xz/list.c:781
#, c-format
msgid ""
" Blocks:\n"
-" Stream Block CompOffset UncompOffset TotalSize "
-"UncompSize Ratio Check"
+" Stream Block CompOffset UncompOffset TotalSize UncompSize Ratio Check"
msgstr ""
" Blocchi:\n"
-" Stream Blocc. Offset comp. Offset estratto Dim. tot. Dim. "
-"estratto Rapp. Contr"
+" Stream Blocc. Offset comp. Offset estratto Dim. tot. Dim. estratto Rapp. Contr"
#. TRANSLATORS: These are additional column headings
#. for the most verbose listing mode. CheckVal
@@ -377,160 +361,149 @@
#. are right aligned. %*s is replaced with 0-120
#. spaces to make the CheckVal column wide enough.
#. Test with "xz -lvv foo.xz".
-#: ../src/xz/list.c:760
+#: src/xz/list.c:793
#, c-format
msgid " CheckVal %*s Header Flags CompSize MemUsage Filters"
msgstr " Val.cont %*s Header Flag Dim.compr. Uso mem. Filtri"
-#: ../src/xz/list.c:838 ../src/xz/list.c:1007
+#: src/xz/list.c:871 src/xz/list.c:1046
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Memoria necessaria: %s MiB\n"
-#: ../src/xz/list.c:840 ../src/xz/list.c:1009
+#: src/xz/list.c:873 src/xz/list.c:1048
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Dim. negli header: %s\n"
-#: ../src/xz/list.c:841 ../src/xz/list.c:1010
+#: src/xz/list.c:874 src/xz/list.c:1049
msgid "Yes"
msgstr "Sì"
-#: ../src/xz/list.c:841 ../src/xz/list.c:1010
+#: src/xz/list.c:874 src/xz/list.c:1049
msgid "No"
msgstr "No"
-#. Since we print totals only when there are at least two files,
-#. the English message will always use "%s files". But some other
-#. languages need different forms for different plurals so we
-#. have to translate this with ngettext().
-#.
+#: src/xz/list.c:875 src/xz/list.c:1050
+#, c-format
+msgid " Minimum XZ Utils version: %s\n"
+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:986
+#: src/xz/list.c:1025
#, 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:999
+#: src/xz/list.c:1038
msgid "Totals:"
msgstr "Totali:"
-#: ../src/xz/list.c:1000
+#: src/xz/list.c:1039
#, c-format
msgid " Number of files: %s\n"
msgstr " Numero di file: %s\n"
-#: ../src/xz/list.c:1072
+#: src/xz/list.c:1114
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:1078
+#: src/xz/list.c:1120
msgid "--list does not support reading from standard input"
msgstr "--list non è in grado di leggere dallo standard input"
-#: ../src/xz/main.c:89
+#: src/xz/main.c:89
#, c-format
msgid "%s: Error reading filenames: %s"
msgstr "%s: errore nel leggere i nomi dei file: %s"
-#: ../src/xz/main.c:96
+#: src/xz/main.c:96
#, 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"
-#. A null character was found when using --files,
-#. which expects plain text input separated with
-#. newlines.
-#: ../src/xz/main.c:120
+#: src/xz/main.c:120
#, c-format
-msgid ""
-"%s: Null character found when reading filenames; maybe you meant to use `--"
-"files0' instead of `--files'?"
-msgstr ""
-"%s: nessun carattere trovato durante la lettura dei nomi dei file; forse si "
-"intendeva usare \"--files0\" invece di \"--files\"?"
+msgid "%s: Null character found when reading filenames; maybe you meant to use `--files0' instead of `--files'?"
+msgstr "%s: nessun carattere trovato durante la lettura dei nomi dei file; forse si intendeva usare \"--files0\" invece di \"--files\"?"
-#: ../src/xz/main.c:174
+#: src/xz/main.c:174
msgid "Compression and decompression with --robot are not supported yet."
msgstr "La compressione e l'estrazione con --robot non sono ancora supportate."
-#: ../src/xz/main.c:231
-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"
+#: src/xz/main.c:231
+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:733
+#: src/xz/message.c:733
#, c-format
msgid "%s: "
msgstr "%s: "
-#: ../src/xz/message.c:796 ../src/xz/message.c:846
+#: src/xz/message.c:796 src/xz/message.c:846
msgid "Internal error (bug)"
msgstr "Errore interno (bug)"
-#: ../src/xz/message.c:803
+#: src/xz/message.c:803
msgid "Cannot establish signal handlers"
msgstr "Impossibile stabilire i gestori dei segnali"
-#: ../src/xz/message.c:812
+#: src/xz/message.c:812
msgid "No integrity check; not verifying file integrity"
-msgstr ""
-"Nessun controllo d'integrità; l'integrità del file non viene verificata"
+msgstr "Nessun controllo d'integrità; l'integrità del file non viene verificata"
-#: ../src/xz/message.c:815
+#: src/xz/message.c:815
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"
+msgstr "Tipo di controllo di integrità non supportato; l'integrità del file non viene verificata"
-#: ../src/xz/message.c:822
+#: src/xz/message.c:822
msgid "Memory usage limit reached"
msgstr "Limite di utilizzo della memoria raggiunto"
-#: ../src/xz/message.c:825
+#: src/xz/message.c:825
msgid "File format not recognized"
msgstr "Formato di file non riconosciuto"
-#: ../src/xz/message.c:828
+#: src/xz/message.c:828
msgid "Unsupported options"
msgstr "Opzioni non supportate"
-#: ../src/xz/message.c:831
+#: src/xz/message.c:831
msgid "Compressed data is corrupt"
msgstr "I dati compressi sono danneggiati"
-#: ../src/xz/message.c:834
+#: src/xz/message.c:834
msgid "Unexpected end of input"
msgstr "Fine dell'input non attesa"
-#: ../src/xz/message.c:885
+#: src/xz/message.c:867
+#, fuzzy, c-format
+msgid "%s MiB of memory is required. The limiter is disabled."
+msgstr "%s MiB di memoria sono richiesti. Il limite è %s."
+
+#: src/xz/message.c:895
#, 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:1052
+#: src/xz/message.c:1062
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s: catena di filtri: %s\n"
-#. Print this with V_WARNING instead of V_ERROR to prevent it from
-#. showing up when --quiet has been specified.
-#: ../src/xz/message.c:1062
+#: src/xz/message.c:1072
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Provare \"%s --help\" per maggiori informazioni."
-#: ../src/xz/message.c:1088
+#: src/xz/message.c:1098
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
@@ -541,18 +514,15 @@
"Comprime o estrae i FILE nel formato .xz.\n"
"\n"
-#: ../src/xz/message.c:1095
-msgid ""
-"Mandatory arguments to long options are mandatory for short options too.\n"
-msgstr ""
-"Gli argomenti obbligatori per le opzioni lunghe lo sono anche per quelle "
-"brevi.\n"
+#: src/xz/message.c:1105
+msgid "Mandatory arguments to long options are mandatory for short options too.\n"
+msgstr "Gli argomenti obbligatori per le opzioni lunghe lo sono anche per quelle brevi.\n"
-#: ../src/xz/message.c:1099
+#: src/xz/message.c:1109
msgid " Operation mode:\n"
msgstr " Modalità di operazione:\n"
-#: ../src/xz/message.c:1102
+#: src/xz/message.c:1112
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
@@ -564,7 +534,7 @@
" -t, --test Verifica l'integrità dei file compressi\n"
" -l, --list Elenca informazioni sui file .xz"
-#: ../src/xz/message.c:1108
+#: src/xz/message.c:1118
msgid ""
"\n"
" Operation modifiers:\n"
@@ -572,20 +542,18 @@
"\n"
" Modificatori di operazioni:\n"
-#: ../src/xz/message.c:1111
+#: src/xz/message.c:1121
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 Mantiene (non elimina) i file di input\n"
-" -f, --force Forza la sovrascrittura dell'output e comprime/estrae "
-"i\n"
+" -f, --force Forza la sovrascrittura dell'output e comprime/estrae i\n"
" collegamenti\n"
-" -c, --stdout Scrive sullo standard output e non elimina i file di "
-"input"
+" -c, --stdout Scrive sullo standard output e non elimina i file di input"
-#: ../src/xz/message.c:1117
+#: src/xz/message.c:1127
msgid ""
" --single-stream decompress only the first stream, and silently\n"
" ignore possible remaining input data"
@@ -593,27 +561,24 @@
" --single-stream Decomprime solamente il primo stream e ignora\n"
" silenziosamente i restanti dati di input"
-#: ../src/xz/message.c:1120
+#: src/xz/message.c:1130
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"
+" filenames must be terminated with the newline character\n"
" --files0[=FILE] like --files but use the null character as terminator"
msgstr ""
" --no-sparse Non crea file sparsi durante l'estrazione\n"
" -S, --suffix=.SUF Usa il suffisso \".SUF\" sui file compressi\n"
" --files=[FILE] Legge i nomi dei file da elaborare da FILE; se FILE è\n"
-" omesso, i nomi dei file sono letti dallo standard "
-"input;\n"
-" i nomi dei file devono essere terminati con un "
-"carattere\n"
+" omesso, i nomi dei file sono letti dallo standard input;\n"
+" i nomi dei file devono essere terminati con un carattere\n"
" di newline\n"
" --files0=[FILE] Come --files ma usa il carattere null come terminatore"
-#: ../src/xz/message.c:1129
+#: src/xz/message.c:1139
msgid ""
"\n"
" Basic file format and compression options:\n"
@@ -621,46 +586,37 @@
"\n"
" Formato file di base e opzioni di compressione:\n"
-#: ../src/xz/message.c:1131
+#: src/xz/message.c:1141
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'"
msgstr ""
-" -F, --format=FMT Formato file per codificare o decodificare; i "
-"possibili\n"
-" valori sono \"auto\" (predefinito) \"xz\", \"lzma\" e "
-"\"raw\"\n"
-" -C, --check=CHECK Tipo di verifica integrità: \"none\" (usare con "
-"attenzione),\n"
+" -F, --format=FMT Formato file per codificare o decodificare; i possibili\n"
+" valori sono \"auto\" (predefinito) \"xz\", \"lzma\" e \"raw\"\n"
+" -C, --check=CHECK Tipo di verifica integrità: \"none\" (usare con attenzione),\n"
" \"crc32\", \"crc64\" (predefinito) o \"sha256\""
-#: ../src/xz/message.c:1138
+#: src/xz/message.c:1148
msgid ""
-" -0 ... -9 compression preset; default is 6; take compressor "
-"*and*\n"
-" decompressor memory usage into account before using "
-"7-9!"
+" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
+" decompressor memory usage into account before using 7-9!"
msgstr ""
-" -0 ... -9 Preset di compressione; predefinito è 6; tenere a "
-"mente\n"
-" l'utilizzo di memoria per comprimere ed estrarre "
-"prima\n"
+" -0 ... -9 Preset di compressione; predefinito è 6; tenere a mente\n"
+" l'utilizzo di memoria per comprimere ed estrarre prima\n"
" di usare 7-9"
-#: ../src/xz/message.c:1142
+#: src/xz/message.c:1152
msgid ""
-" -e, --extreme try to improve compression ratio by using more CPU "
-"time;\n"
+" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" does not affect decompressor memory requirements"
msgstr ""
" -e, --extreme Tenta di migliorare il rapporto di compressione\n"
-" utilizzando più tempo di CPU; non cambia i requisiti "
-"di\n"
+" utilizzando più tempo di CPU; non cambia i requisiti di\n"
" memoria in fase di estrazione"
-#: ../src/xz/message.c:1147
+#: src/xz/message.c:1158
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
@@ -670,37 +626,43 @@
" Comprimendo nel formato .zx, comincia un nuovo blocco\n"
" dopo DIM byte di input; 0=disabilitato (predefinito)"
-#: ../src/xz/message.c:1151
+#: src/xz/message.c:1163
+#, fuzzy
+msgid ""
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"
+msgstr ""
+" --block-size=DIM \n"
+" Comprimendo nel formato .zx, comincia un nuovo blocco\n"
+" dopo DIM byte di input; 0=disabilitato (predefinito)"
+
+#: src/xz/message.c:1167
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
-" set memory usage limit for compression, "
-"decompression,\n"
+" set memory usage limit for compression, decompression,\n"
" or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
msgstr ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
" Imposta il limite di utilizzo della memoria per la\n"
-" compressione, l'estrazione o entrambe; LIMIT è in "
-"byte,\n"
+" compressione, l'estrazione o entrambe; LIMIT è in byte,\n"
" % della memoria RAM oppure 0 per il valore predefinito"
-#: ../src/xz/message.c:1158
+#: src/xz/message.c:1174
msgid ""
-" --no-adjust if compression settings exceed the memory usage "
-"limit,\n"
-" give an error instead of adjusting the settings "
-"downwards"
+" --no-adjust if compression settings exceed the memory usage limit,\n"
+" give an error instead of adjusting the settings downwards"
msgstr ""
-" --no-adjust Se le impostazioni di compressione eccedono il limite "
-"di\n"
+" --no-adjust Se le impostazioni di compressione eccedono il limite di\n"
" utilizzo della memoria, lancia un errore invece di\n"
" utilizzare valori più piccoli"
-#: ../src/xz/message.c:1164
+#: src/xz/message.c:1180
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -709,13 +671,11 @@
" Catena di filtri personalizzati per la compressione (alternative per\n"
" l'utilizzo di preset):"
-#: ../src/xz/message.c:1173
+#: src/xz/message.c:1189
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"
+" --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"
@@ -723,24 +683,17 @@
" 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)"
+" mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
+" depth=NUM maximum search depth; 0=automatic (default)"
msgstr ""
"\n"
-" --lzma1[=OPZ] LZMA1 o LZMA2; OPZ è un elenco separato da virgole di "
-"zero\n"
-" --lzma2[=OPZ] o più delle seguenti opzioni (valori validi; "
-"predefinito):\n"
-" preset=NUM Reimposta le opzioni al preset NUM (0-9"
-"[e])\n"
+" --lzma1[=OPZ] LZMA1 o LZMA2; OPZ è un elenco separato da virgole di zero\n"
+" --lzma2[=OPZ] o più delle seguenti opzioni (valori validi; predefinito):\n"
+" preset=NUM Reimposta le opzioni al preset NUM (0-9[e])\n"
" dict=NUM Dimensione del dizionario\n"
" (4KiB - 1536MiB; 8MiB)\n"
-" lc=NUM Numero di bit letterali di contesto (0-4; "
-"3)\n"
-" lp=NUM Numero di bit letterali di posizione "
-"(0-4; 0)\n"
+" lc=NUM Numero di bit letterali di contesto (0-4; 3)\n"
+" lp=NUM Numero di bit letterali di posizione (0-4; 0)\n"
" pb=NUM Numero di bit di posizione (0-4; 2)\n"
" mode=MODE Modalità di compressione\n"
" (fast, normal; normal)\n"
@@ -748,11 +701,10 @@
" (2-273; 64)\n"
" mf=NAME Strumento per cercare corrispondenze\n"
" (hc3, hc4, bt2, bt3, bt4; bt4)\n"
-" depth=NUM Profondità massima di ricerca; "
-"0=automatica\n"
+" depth=NUM Profondità massima di ricerca; 0=automatica\n"
" (predefinito)"
-#: ../src/xz/message.c:1188
+#: src/xz/message.c:1204
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -775,7 +727,7 @@
" start=NUM Offset iniziale per le conversioni\n"
" (predefinito=0)"
-#: ../src/xz/message.c:1200
+#: src/xz/message.c:1216
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -787,7 +739,7 @@
" dist=NUM Distanza tra byte sottratti\n"
" gli uni dagli altri (1-256; 1)"
-#: ../src/xz/message.c:1208
+#: src/xz/message.c:1224
msgid ""
"\n"
" Other options:\n"
@@ -795,39 +747,33 @@
"\n"
" Altre opzioni:\n"
-#: ../src/xz/message.c:1211
+#: src/xz/message.c:1227
msgid ""
-" -q, --quiet suppress warnings; specify twice to suppress errors "
-"too\n"
+" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
msgstr ""
-" -q, --quiet Sopprime gli avvisi; specificare due volte per "
-"sopprimere\n"
+" -q, --quiet Sopprime gli avvisi; specificare due volte per sopprimere\n"
" anche gli errori\n"
-" -v, --verbose Output prolisso; specificare due volte per output "
-"ancora\n"
+" -v, --verbose Output prolisso; specificare due volte per output ancora\n"
" più prolisso"
-#: ../src/xz/message.c:1216
+#: src/xz/message.c:1232
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn Gli avvisi non influenzano lo stato d'uscita"
-#: ../src/xz/message.c:1218
-msgid ""
-" --robot use machine-parsable messages (useful for scripts)"
+#: src/xz/message.c:1234
+msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr " --robot Usa messaggi analizzabili (utile per gli script)"
-#: ../src/xz/message.c:1221
+#: src/xz/message.c:1237
msgid ""
-" --info-memory display the total amount of RAM and the currently "
-"active\n"
+" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
msgstr ""
-" --info-memory Visualizza la quantità totale di RAM, il limite "
-"attuale\n"
+" --info-memory Visualizza la quantità totale di RAM, il limite attuale\n"
" attivo di utilizzo della memore ed esce"
-#: ../src/xz/message.c:1224
+#: src/xz/message.c:1240
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -835,7 +781,7 @@
" -h, --help Stampa l'aiuto breve (elenca solo le opzioni di base)\n"
" -H, --long-help Stampa questo lungo aiuto ed esce"
-#: ../src/xz/message.c:1228
+#: src/xz/message.c:1244
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
@@ -843,11 +789,11 @@
" -h, --help Stampa questo breve aiuto ed esce\n"
" -H, --long-help Stampa l'aiuto lungo (elenca anche le opzioni avanzate)"
-#: ../src/xz/message.c:1233
+#: src/xz/message.c:1249
msgid " -V, --version display the version number and exit"
msgstr " -V, --version Stampa il numero della versione ed esce"
-#: ../src/xz/message.c:1235
+#: src/xz/message.c:1251
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -859,111 +805,102 @@
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
-#: ../src/xz/message.c:1241
+#: src/xz/message.c:1257
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
"Segnalare i bug a <%s> (in inglese o finlandese).\n"
"Segnalare i bug di traduzione a <tp@lists.linux.it>.\n"
-#: ../src/xz/message.c:1243
+#: src/xz/message.c:1259
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Sito web di %s: <%s>\n"
-#: ../src/xz/options.c:86
+#: src/xz/options.c:86
#, c-format
msgid "%s: Options must be `name=value' pairs separated with commas"
-msgstr ""
-"%s: le opzioni devono essere coppie \"nome=valore\" separate da virgole"
+msgstr "%s: le opzioni devono essere coppie \"nome=valore\" separate da virgole"
-#: ../src/xz/options.c:93
+#: src/xz/options.c:93
#, c-format
msgid "%s: Invalid option name"
msgstr "%s: nome opzione non valido"
-#: ../src/xz/options.c:113
+#: src/xz/options.c:113
#, c-format
msgid "%s: Invalid option value"
msgstr "%s: valore dell'opzione non valido"
-#: ../src/xz/options.c:247
+#: src/xz/options.c:247
#, c-format
msgid "Unsupported LZMA1/LZMA2 preset: %s"
msgstr "Preset LZMA/LZMA2 non supportato: %s"
-#: ../src/xz/options.c:355
+#: src/xz/options.c:355
msgid "The sum of lc and lp must not exceed 4"
msgstr "La somma di lc e lp non deve superare 4"
-#: ../src/xz/options.c:359
+#: src/xz/options.c:359
#, c-format
msgid "The selected match finder requires at least nice=%<PRIu32>"
-msgstr ""
-"Lo strumento per cercare corrispondenze selezionato richiede almeno nice="
-"%<PRIu32>"
+msgstr "Lo strumento per cercare corrispondenze selezionato richiede almeno nice=%<PRIu32>"
-#: ../src/xz/suffix.c:133 ../src/xz/suffix.c:258
+#: src/xz/suffix.c:133 src/xz/suffix.c:258
#, c-format
-msgid ""
-"%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
-msgstr ""
-"%s: con --format=raw, --suffix=.SUF è richiesto a meno che non si scriva "
-"sullo stdout"
+msgid "%s: With --format=raw, --suffix=.SUF is required unless writing to stdout"
+msgstr "%s: con --format=raw, --suffix=.SUF è richiesto a meno che non si scriva sullo stdout"
-#: ../src/xz/suffix.c:164
+#: src/xz/suffix.c:164
#, 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:185
+#: src/xz/suffix.c:185
#, c-format
msgid "%s: File already has `%s' suffix, skipping"
msgstr "%s: il file ha già il suffisso \"%s\", viene saltato"
-#: ../src/xz/suffix.c:393
+#: src/xz/suffix.c:393
#, c-format
msgid "%s: Invalid filename suffix"
msgstr "%s: suffisso del nome del file non valido"
-#: ../src/xz/util.c:61
+#: src/xz/util.c:61
#, c-format
msgid "%s: Value is not a non-negative decimal integer"
msgstr "%s: il valore non è un numero intero decimale non-negativo"
-#: ../src/xz/util.c:103
+#: src/xz/util.c:103
#, c-format
msgid "%s: Invalid multiplier suffix"
msgstr "%s: suffisso del moltiplicatore non valido"
-#: ../src/xz/util.c:105
+#: src/xz/util.c:105
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)."
+msgstr "I suffissi validi sono \"KiB\" (2^10), \"MiB\" (2^20), e \"GiB\" (2^30)."
-#: ../src/xz/util.c:122
+#: src/xz/util.c:122
#, c-format
msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
-msgstr ""
-"Il valore dell'opzione \"%s\" deve essere nell'intervallo [%<PRIu64>, "
-"%<PRIu64>]"
+msgstr "Il valore dell'opzione \"%s\" deve essere nell'intervallo [%<PRIu64>, %<PRIu64>]"
-#: ../src/xz/util.c:247
+#: src/xz/util.c:247
msgid "Empty filename, skipping"
msgstr "Nome file vuoto, viene saltato"
-#: ../src/xz/util.c:261
+#: src/xz/util.c:261
msgid "Compressed data cannot be read from a terminal"
msgstr "I dati compressi non possono essere letti da un terminale"
-#: ../src/xz/util.c:274
+#: src/xz/util.c:274
msgid "Compressed data cannot be written to a terminal"
msgstr "I dati compressi non possono essere scritti ad un terminale"
-#: ../src/common/tuklib_exit.c:39
+#: src/common/tuklib_exit.c:39
msgid "Writing to standard output failed"
msgstr "Scrittura sullo standard ouput non riuscita"
-#: ../src/common/tuklib_exit.c:42
+#: src/common/tuklib_exit.c:42
msgid "Unknown error"
msgstr "Errore sconosciuto"
diff --git a/po/pl.po b/po/pl.po
index 55deda1..0f3e96c 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@
msgstr ""
"Project-Id-Version: xz 5.1.1\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
-"POT-Creation-Date: 2012-05-29 13:59+0300\n"
+"POT-Creation-Date: 2012-07-04 20:51+0300\n"
"PO-Revision-Date: 2012-05-29 18:15+0200\n"
"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
@@ -16,69 +16,83 @@
"Content-Transfer-Encoding: 8bit\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:338
+#: src/xz/args.c:62
+#, c-format
+msgid "%s: Invalid argument to --block-list"
+msgstr ""
+
+#: src/xz/args.c:72
+#, c-format
+msgid "%s: Too many arguments to --block-list"
+msgstr ""
+
+#: src/xz/args.c:101
+msgid "0 can only be used as the last element in --block-list"
+msgstr ""
+
+#: src/xz/args.c:401
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Nieznany typ formatu pliku"
-#: src/xz/args.c:361 src/xz/args.c:369
+#: src/xz/args.c:424 src/xz/args.c:432
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Nieobsługiwany typ kontroli spójności"
-#: src/xz/args.c:396
+#: src/xz/args.c:464
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Wraz z opcją `--files' lub `--files0' można podać tylko jeden plik."
-#: src/xz/args.c:459
+#: src/xz/args.c:527
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Zmienna środowiskowa %s zawiera zbyt dużo argumentów"
-#: src/xz/coder.c:105
+#: src/xz/coder.c:106
msgid "Maximum number of filters is four"
msgstr "Maksymalna liczba filtrów to cztery"
-#: src/xz/coder.c:118
+#: src/xz/coder.c:119
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:148
+#: src/xz/coder.c:149
msgid "Using a preset in raw mode is discouraged."
msgstr "Użycie ustawień predefiniowanych w trybie surowym jest odradzane."
-#: src/xz/coder.c:150
+#: src/xz/coder.c:151
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:176
+#: src/xz/coder.c:177
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Format .lzma obsługuje tylko filtr LZMA1"
-#: src/xz/coder.c:184
+#: src/xz/coder.c:185
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 nie może być używany z formatem .xz"
-#: src/xz/coder.c:203
+#: src/xz/coder.c:204
#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Maksymalna liczba używanych wątków: %<PRIu32>."
-#: src/xz/coder.c:216
+#: src/xz/coder.c:217
msgid "Unsupported filter chain or filter options"
msgstr "Nieobsługiwany łańcuch filtrów lub opcje filtra"
-#: src/xz/coder.c:224
+#: src/xz/coder.c:225
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "Dekompresja będzie wymagała %s MiB pamięci."
-#: src/xz/coder.c:259
+#: src/xz/coder.c:260
#, c-format
msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
msgstr "Skorygowano liczbę wątków z %s do %s, aby nie przekroczyć limitu użycia pamięci %s MiB"
-#: src/xz/coder.c:313
+#: src/xz/coder.c:314
#, 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"
@@ -599,7 +613,7 @@
" ilości czasu procesora; nie wpływa na wymagania\n"
" pamięciowe dekompresora"
-#: src/xz/message.c:1157
+#: src/xz/message.c:1158
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
@@ -609,7 +623,18 @@
" przy kompresji do formatu .xz: rozpoczynanie nowego bloku\n"
" po każdej LICZBIE bajtów wejścia; 0=wyłączone (domyślne)"
-#: src/xz/message.c:1161
+#: src/xz/message.c:1163
+#, fuzzy
+msgid ""
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"
+msgstr ""
+" --block-size=LICZBA\n"
+" przy kompresji do formatu .xz: rozpoczynanie nowego bloku\n"
+" po każdej LICZBIE bajtów wejścia; 0=wyłączone (domyślne)"
+
+#: src/xz/message.c:1167
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
@@ -625,7 +650,7 @@
" dekompresji lub obu; LIMIT jest w bajtach, % RAM lub 0\n"
" dla limitów domyślnych"
-#: src/xz/message.c:1168
+#: src/xz/message.c:1174
msgid ""
" --no-adjust if compression settings exceed the memory usage limit,\n"
" give an error instead of adjusting the settings downwards"
@@ -634,7 +659,7 @@
" pamięci, zostanie zgłoszony błąd zamiast zmniejszania\n"
" ustawień"
-#: src/xz/message.c:1174
+#: src/xz/message.c:1180
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -642,7 +667,7 @@
"\n"
" Łańcuch własnych filtrów do kompresji (alternatywa do używania -0 .. -9):"
-#: src/xz/message.c:1183
+#: src/xz/message.c:1189
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -671,7 +696,7 @@
" mf=NAZWA dopasowywacz (hc3, hc4, bt2, bt3, bt4; bt4)\n"
" depth=ILE maks. głębokość szukania; 0=auto (domyślne)"
-#: src/xz/message.c:1198
+#: src/xz/message.c:1204
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -693,7 +718,7 @@
" Poprawne OPCJE dla wszystkich filtrów BCJ:\n"
" start=ILE offset początku konwersji (domyślnie=0)"
-#: src/xz/message.c:1210
+#: src/xz/message.c:1216
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -705,7 +730,7 @@
" dist=ILE odległość między bajtami odejmowanymi od\n"
" siebie (1-256; 1)"
-#: src/xz/message.c:1218
+#: src/xz/message.c:1224
msgid ""
"\n"
" Other options:\n"
@@ -713,7 +738,7 @@
"\n"
" Inne opcje:\n"
-#: src/xz/message.c:1221
+#: src/xz/message.c:1227
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
@@ -721,15 +746,15 @@
" -q, --quiet pominięcie ostrzeżeń; dwukrotne podanie pomija też błędy\n"
" -v, --verbose więcej informacji; dwukrotne podanie to jeszcze więcej"
-#: src/xz/message.c:1226
+#: src/xz/message.c:1232
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn ostrzeżenia nie mają wpływu na status zakończenia"
-#: src/xz/message.c:1228
+#: src/xz/message.c:1234
msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr " --robot komunikaty w formacie dla maszyny (do skryptów)"
-#: src/xz/message.c:1231
+#: src/xz/message.c:1237
msgid ""
" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
@@ -737,7 +762,7 @@
" --info-memory wyświetlenie całkowitej ilości pamięci RAM oraz aktualnie\n"
" aktywnych limitów pamięci i zakończenie pracy"
-#: src/xz/message.c:1234
+#: src/xz/message.c:1240
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -745,7 +770,7 @@
" -h, --help wyświetlenie krótkiego opisu (tylko podstawowe opcje)\n"
" -H, --long-help wyświetlenie tego długiego opisu i zakończenie"
-#: src/xz/message.c:1238
+#: src/xz/message.c:1244
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
@@ -753,11 +778,11 @@
" -h, --help wyświetlenie tego krótkiego opisu i zakończenie\n"
" -H, --long-help wyświetlenie długiego opisu (także opcje zaawansowane)"
-#: src/xz/message.c:1243
+#: src/xz/message.c:1249
msgid " -V, --version display the version number and exit"
msgstr " -V, --version wyświetlenie informacji o wersji i zakończenie"
-#: src/xz/message.c:1245
+#: src/xz/message.c:1251
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -769,7 +794,7 @@
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
-#: src/xz/message.c:1251
+#: src/xz/message.c:1257
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
@@ -778,7 +803,7 @@
"Błędy w tłumaczeniu prosimy zgłaszać na adres\n"
"<translation-team-pl@lists.sourceforge.net>.\n"
-#: src/xz/message.c:1253
+#: src/xz/message.c:1259
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Strona domowa %s: <%s>\n"
diff --git a/src/liblzma/Makefile.am b/src/liblzma/Makefile.am
index ac2d1ed..5bd205d 100644
--- a/src/liblzma/Makefile.am
+++ b/src/liblzma/Makefile.am
@@ -24,7 +24,7 @@
-I$(top_srcdir)/src/liblzma/simple \
-I$(top_srcdir)/src/common \
-DTUKLIB_SYMBOL_PREFIX=lzma_
-liblzma_la_LDFLAGS = -no-undefined -version-info 5:0:0
+liblzma_la_LDFLAGS = -no-undefined -version-info 5:99:0
if COND_SYMVERS
EXTRA_DIST += liblzma.map
diff --git a/src/liblzma/api/lzma/container.h b/src/liblzma/api/lzma/container.h
index 7a9ffc6..499d8b9 100644
--- a/src/liblzma/api/lzma/container.h
+++ b/src/liblzma/api/lzma/container.h
@@ -60,6 +60,129 @@
#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
+#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
+/**
+ * \brief Multithreading options
+ */
+typedef struct {
+ /**
+ * \brief Flags
+ *
+ * Set this to zero if no flags are wanted.
+ *
+ * No flags are currently supported.
+ */
+ uint32_t flags;
+
+ /**
+ * \brief Number of worker threads to use
+ */
+ uint32_t threads;
+
+ /**
+ * \brief Maximum uncompressed size of a Block
+ *
+ * The encoder will start a new .xz Block every block_size bytes.
+ * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()
+ * the caller may tell liblzma to start a new Block earlier.
+ *
+ * With LZMA2, a recommended block size is 2-4 times the LZMA2
+ * dictionary size. With very small dictionaries, it is recommended
+ * to use at least 1 MiB block size for good compression ratio, even
+ * if this is more than four times the dictionary size. Note that
+ * these are only recommendations for typical use cases; feel free
+ * to use other values. Just keep in mind that using a block size
+ * less than the LZMA2 dictionary size is waste of RAM.
+ *
+ * Set this to 0 to let liblzma choose the block size depending
+ * on the compression options. For LZMA2 it will be 3*dict_size
+ * or 1 MiB, whichever is more.
+ */
+ uint64_t block_size;
+
+ /**
+ * \brief Timeout to allow lzma_code() to return early
+ *
+ * Multithreading can make liblzma to consume input and produce
+ * output in a very bursty way: it may first read a lot of input
+ * to fill internal buffers, then no input or output occurs for
+ * a while.
+ *
+ * In single-threaded mode, lzma_code() won't return until it has
+ * either consumed all the input or filled the output buffer. If
+ * this is done in multithreaded mode, it may cause a call
+ * lzma_code() to take even tens of seconds, which isn't acceptable
+ * in all applications.
+ *
+ * To avoid very long blocking times in lzma_code(), a timeout
+ * (in milliseconds) may be set here. If lzma_code() would block
+ * longer than this number of milliseconds, it will return with
+ * LZMA_OK. Reasonable values are 100 ms or more. The xz command
+ * line tool uses 300 ms.
+ *
+ * If long blocking times are fine for you, set timeout to a special
+ * value of 0, which will disable the timeout mechanism and will make
+ * lzma_code() block until all the input is consumed or the output
+ * buffer has been filled.
+ *
+ * \note Even with a timeout, lzma_code() might sometimes take
+ * somewhat long time to return. No timing guarantees
+ * are made.
+ */
+ uint32_t timeout;
+
+ /**
+ * \brief Compression preset (level and possible flags)
+ *
+ * The preset is set just like with lzma_easy_encoder().
+ * The preset is ignored if filters below is non-NULL.
+ */
+ uint32_t preset;
+
+ /**
+ * \brief Filter chain (alternative to a preset)
+ *
+ * If this is NULL, the preset above is used. Otherwise the preset
+ * is ignored and the filter chain specified here is used.
+ */
+ const lzma_filter *filters;
+
+ /**
+ * \brief Integrity check type
+ *
+ * See check.h for available checks. The xz command line tool
+ * defaults to LZMA_CHECK_CRC64, which is a good choice if you
+ * are unsure.
+ */
+ lzma_check check;
+
+ /*
+ * Reserved space to allow possible future extensions without
+ * breaking the ABI. You should not touch these, because the names
+ * of these variables may change. These are and will never be used
+ * with the currently supported options, so it is safe to leave these
+ * uninitialized.
+ */
+ lzma_reserved_enum reserved_enum1;
+ lzma_reserved_enum reserved_enum2;
+ lzma_reserved_enum reserved_enum3;
+ uint32_t reserved_int1;
+ uint32_t reserved_int2;
+ uint32_t reserved_int3;
+ uint32_t reserved_int4;
+ uint64_t reserved_int5;
+ uint64_t reserved_int6;
+ uint64_t reserved_int7;
+ uint64_t reserved_int8;
+ void *reserved_ptr1;
+ void *reserved_ptr2;
+ void *reserved_ptr3;
+ void *reserved_ptr4;
+
+} lzma_mt;
+#endif
+
+
/**
* \brief Calculate approximate memory usage of easy encoder
*
@@ -190,6 +313,50 @@
lzma_nothrow lzma_attr_warn_unused_result;
+#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
+/**
+ * \brief Calculate approximate memory usage of multithreaded .xz encoder
+ *
+ * Since doing the encoding in threaded mode doesn't affect the memory
+ * requirements of single-threaded decompressor, you can use
+ * lzma_easy_decoder_memusage(options->preset) or
+ * lzma_raw_decoder_memusage(options->filters) to calculate
+ * the decompressor memory requirements.
+ *
+ * \param options Compression options
+ *
+ * \return Number of bytes of memory required for encoding with the
+ * given options. If an error occurs, for example due to
+ * unsupported preset or filter chain, UINT64_MAX is returned.
+ */
+extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
+ const lzma_mt *options) lzma_nothrow lzma_attr_pure;
+
+
+/**
+ * \brief Initialize multithreaded .xz Stream encoder
+ *
+ * This provides the functionality of lzma_easy_encoder() and
+ * lzma_stream_encoder() as a single function for multithreaded use.
+ *
+ * TODO: For lzma_code(), only LZMA_RUN and LZMA_FINISH are currently
+ * supported. Support for other actions has been planned.
+ *
+ * \param strm Pointer to properly prepared lzma_stream
+ * \param options Pointer to multithreaded compression options
+ *
+ * \return - LZMA_OK
+ * - LZMA_MEM_ERROR
+ * - LZMA_UNSUPPORTED_CHECK
+ * - LZMA_OPTIONS_ERROR
+ * - LZMA_PROG_ERROR
+ */
+extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
+ lzma_stream *strm, const lzma_mt *options)
+ lzma_nothrow lzma_attr_warn_unused_result;
+#endif
+
+
/**
* \brief Initialize .lzma encoder (legacy file format)
*
diff --git a/src/liblzma/api/lzma/version.h b/src/liblzma/api/lzma/version.h
index a908ea2..cba794f 100644
--- a/src/liblzma/api/lzma/version.h
+++ b/src/liblzma/api/lzma/version.h
@@ -22,7 +22,7 @@
*/
#define LZMA_VERSION_MAJOR 5
#define LZMA_VERSION_MINOR 1
-#define LZMA_VERSION_PATCH 0
+#define LZMA_VERSION_PATCH 2
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
#ifndef LZMA_VERSION_COMMIT
diff --git a/src/liblzma/common/Makefile.inc b/src/liblzma/common/Makefile.inc
index 81d751e..dd5a8c8 100644
--- a/src/liblzma/common/Makefile.inc
+++ b/src/liblzma/common/Makefile.inc
@@ -40,6 +40,13 @@
common/stream_encoder.c \
common/stream_flags_encoder.c \
common/vli_encoder.c
+
+if COND_THREADS
+liblzma_la_SOURCES += \
+ common/outqueue.c \
+ common/outqueue.h \
+ common/stream_encoder_mt.c
+endif
endif
if COND_MAIN_DECODER
diff --git a/src/liblzma/common/common.c b/src/liblzma/common/common.c
index 3bfdb75..7a2c6ea 100644
--- a/src/liblzma/common/common.c
+++ b/src/liblzma/common/common.c
@@ -329,7 +329,9 @@
strm->internal->avail_in = strm->avail_in;
- switch (ret) {
+ // Cast is needed to silence a warning about LZMA_TIMED_OUT, which
+ // isn't part of lzma_ret enumeration.
+ switch ((unsigned int)(ret)) {
case LZMA_OK:
// Don't return LZMA_BUF_ERROR when it happens the first time.
// This is to avoid returning LZMA_BUF_ERROR when avail_out
@@ -345,6 +347,11 @@
}
break;
+ case LZMA_TIMED_OUT:
+ strm->internal->allow_buf_error = false;
+ ret = LZMA_OK;
+ break;
+
case LZMA_STREAM_END:
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|| strm->internal->sequence == ISEQ_FULL_FLUSH)
diff --git a/src/liblzma/common/common.h b/src/liblzma/common/common.h
index 4081c2d..f2a4552 100644
--- a/src/liblzma/common/common.h
+++ b/src/liblzma/common/common.h
@@ -32,6 +32,8 @@
#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
+#define LZMA_UNSTABLE
+
#include "lzma.h"
// These allow helping the compiler in some often-executed branches, whose
@@ -49,6 +51,13 @@
#define LZMA_BUFFER_SIZE 4096
+/// Maximum number of worker threads within one multithreaded component.
+/// The limit exists solely to make it simpler to prevent integer overflows
+/// when allocating structures etc. This should be big enough for now...
+/// the code won't scale anywhere close to this number anyway.
+#define LZMA_THREADS_MAX 16384
+
+
/// Starting value for memory usage estimates. Instead of calculating size
/// of _every_ structure and taking into account malloc() overhead etc., we
/// add a base size to all memory usage estimates. It's not very accurate
@@ -69,6 +78,13 @@
| LZMA_CONCATENATED )
+/// Special return value (lzma_ret) to indicate that a timeout was reached
+/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
+/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
+/// there's no need to have it in the public API.
+#define LZMA_TIMED_OUT 32
+
+
/// Type of encoder/decoder specific data; the actual structure is defined
/// differently in different coders.
typedef struct lzma_coder_s lzma_coder;
diff --git a/src/liblzma/common/outqueue.c b/src/liblzma/common/outqueue.c
new file mode 100644
index 0000000..d7a87d9
--- /dev/null
+++ b/src/liblzma/common/outqueue.c
@@ -0,0 +1,184 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file outqueue.c
+/// \brief Output queue handling in multithreaded coding
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "outqueue.h"
+
+
+/// This is to ease integer overflow checking: We may allocate up to
+/// 2 * LZMA_THREADS_MAX buffers and we need some extra memory for other
+/// data structures (that's the second /2).
+#define BUF_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX / 2 / 2)
+
+
+static lzma_ret
+get_options(uint64_t *bufs_alloc_size, uint32_t *bufs_count,
+ uint64_t buf_size_max, uint32_t threads)
+{
+ if (threads > LZMA_THREADS_MAX || buf_size_max > BUF_SIZE_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ // The number of buffers is twice the number of threads.
+ // This wastes RAM but keeps the threads busy when buffers
+ // finish out of order.
+ //
+ // NOTE: If this is changed, update BUF_SIZE_MAX too.
+ *bufs_count = threads * 2;
+ *bufs_alloc_size = *bufs_count * buf_size_max;
+
+ return LZMA_OK;
+}
+
+
+extern uint64_t
+lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
+{
+ uint64_t bufs_alloc_size;
+ uint32_t bufs_count;
+
+ if (get_options(&bufs_alloc_size, &bufs_count, buf_size_max, threads)
+ != LZMA_OK)
+ return UINT64_MAX;
+
+ return sizeof(lzma_outq) + bufs_count * sizeof(lzma_outbuf)
+ + bufs_alloc_size;
+}
+
+
+extern lzma_ret
+lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
+ uint64_t buf_size_max, uint32_t threads)
+{
+ uint64_t bufs_alloc_size;
+ uint32_t bufs_count;
+
+ // Set bufs_count and bufs_alloc_size.
+ return_if_error(get_options(&bufs_alloc_size, &bufs_count,
+ buf_size_max, threads));
+
+ // Allocate memory if needed.
+ if (outq->buf_size_max != buf_size_max
+ || outq->bufs_allocated != bufs_count) {
+ lzma_outq_end(outq, allocator);
+
+#if SIZE_MAX < UINT64_MAX
+ if (bufs_alloc_size > SIZE_MAX)
+ return LZMA_MEM_ERROR;
+#endif
+
+ outq->bufs = lzma_alloc(bufs_count * sizeof(lzma_outbuf),
+ allocator);
+ outq->bufs_mem = lzma_alloc((size_t)(bufs_alloc_size),
+ allocator);
+
+ if (outq->bufs == NULL || outq->bufs_mem == NULL) {
+ lzma_outq_end(outq, allocator);
+ return LZMA_MEM_ERROR;
+ }
+ }
+
+ // Initialize the rest of the main structure. Initialization of
+ // outq->bufs[] is done when they are actually needed.
+ outq->buf_size_max = (size_t)(buf_size_max);
+ outq->bufs_allocated = bufs_count;
+ outq->bufs_pos = 0;
+ outq->bufs_used = 0;
+ outq->read_pos = 0;
+
+ return LZMA_OK;
+}
+
+
+extern void
+lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator)
+{
+ lzma_free(outq->bufs, allocator);
+ outq->bufs = NULL;
+
+ lzma_free(outq->bufs_mem, allocator);
+ outq->bufs_mem = NULL;
+
+ return;
+}
+
+
+extern lzma_outbuf *
+lzma_outq_get_buf(lzma_outq *outq)
+{
+ // Caller must have checked it with lzma_outq_has_buf().
+ assert(outq->bufs_used < outq->bufs_allocated);
+
+ // Initialize the new buffer.
+ lzma_outbuf *buf = &outq->bufs[outq->bufs_pos];
+ buf->buf = outq->bufs_mem + outq->bufs_pos * outq->buf_size_max;
+ buf->size = 0;
+ buf->finished = false;
+
+ // Update the queue state.
+ if (++outq->bufs_pos == outq->bufs_allocated)
+ outq->bufs_pos = 0;
+
+ ++outq->bufs_used;
+
+ return buf;
+}
+
+
+extern bool
+lzma_outq_is_readable(const lzma_outq *outq)
+{
+ uint32_t i = outq->bufs_pos - outq->bufs_used;
+ if (outq->bufs_pos < outq->bufs_used)
+ i += outq->bufs_allocated;
+
+ return outq->bufs[i].finished;
+}
+
+
+extern lzma_ret
+lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out,
+ size_t *restrict out_pos, size_t out_size,
+ lzma_vli *restrict unpadded_size,
+ lzma_vli *restrict uncompressed_size)
+{
+ // There must be at least one buffer from which to read.
+ if (outq->bufs_used == 0)
+ return LZMA_OK;
+
+ // Get the buffer.
+ uint32_t i = outq->bufs_pos - outq->bufs_used;
+ if (outq->bufs_pos < outq->bufs_used)
+ i += outq->bufs_allocated;
+
+ lzma_outbuf *buf = &outq->bufs[i];
+
+ // If it isn't finished yet, we cannot read from it.
+ if (!buf->finished)
+ return LZMA_OK;
+
+ // Copy from the buffer to output.
+ lzma_bufcpy(buf->buf, &outq->read_pos, buf->size,
+ out, out_pos, out_size);
+
+ // Return if we didn't get all the data from the buffer.
+ if (outq->read_pos < buf->size)
+ return LZMA_OK;
+
+ // The buffer was finished. Tell the caller its size information.
+ *unpadded_size = buf->unpadded_size;
+ *uncompressed_size = buf->uncompressed_size;
+
+ // Free this buffer for further use.
+ --outq->bufs_used;
+ outq->read_pos = 0;
+
+ return LZMA_STREAM_END;
+}
diff --git a/src/liblzma/common/outqueue.h b/src/liblzma/common/outqueue.h
new file mode 100644
index 0000000..154f91b
--- /dev/null
+++ b/src/liblzma/common/outqueue.h
@@ -0,0 +1,155 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file outqueue.h
+/// \brief Output queue handling in multithreaded coding
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "common.h"
+
+
+/// Output buffer for a single thread
+typedef struct {
+ /// Pointer to the output buffer of lzma_outq.buf_size_max bytes
+ uint8_t *buf;
+
+ /// Amount of data written to buf
+ size_t size;
+
+ /// Additional size information
+ lzma_vli unpadded_size;
+ lzma_vli uncompressed_size;
+
+ /// True when no more data will be written into this buffer.
+ ///
+ /// \note This is read by another thread and thus access
+ /// to this variable needs a mutex.
+ bool finished;
+
+} lzma_outbuf;
+
+
+typedef struct {
+ /// Array of buffers that are used cyclically.
+ lzma_outbuf *bufs;
+
+ /// Memory allocated for all the buffers
+ uint8_t *bufs_mem;
+
+ /// Amount of buffer space available in each buffer
+ size_t buf_size_max;
+
+ /// Number of buffers allocated
+ uint32_t bufs_allocated;
+
+ /// Position in the bufs array. The next buffer to be taken
+ /// into use is bufs[bufs_pos].
+ uint32_t bufs_pos;
+
+ /// Number of buffers in use
+ uint32_t bufs_used;
+
+ /// Position in the buffer in lzma_outq_read()
+ size_t read_pos;
+
+} lzma_outq;
+
+
+/**
+ * \brief Calculate the memory usage of an output queue
+ *
+ * \return Approximate memory usage in bytes or UINT64_MAX on error.
+ */
+extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
+
+
+/// \brief Initialize an output queue
+///
+/// \param outq Pointer to an output queue. Before calling
+/// this function the first time, *outq should
+/// have been zeroed with memzero() so that this
+/// function knows that there are no previous
+/// allocations to free.
+/// \param allocator Pointer to allocator or NULL
+/// \param buf_size_max Maximum amount of data that a single buffer
+/// in the queue may need to store.
+/// \param threads Number of buffers that may be in use
+/// concurrently. Note that more than this number
+/// of buffers will actually get allocated to
+/// improve performance when buffers finish
+/// out of order.
+///
+/// \return - LZMA_OK
+/// - LZMA_MEM_ERROR
+///
+extern lzma_ret lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
+ uint64_t buf_size_max, uint32_t threads);
+
+
+/// \brief Free the memory associated with the output queue
+extern void lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator);
+
+
+/// \brief Get a new buffer
+///
+/// lzma_outq_has_buf() must be used to check that there is a buffer
+/// available before calling lzma_outq_get_buf().
+///
+extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);
+
+
+/// \brief Test if there is data ready to be read
+///
+/// Call to this function must be protected with the same mutex that
+/// is used to protect lzma_outbuf.finished.
+///
+extern bool lzma_outq_is_readable(const lzma_outq *outq);
+
+
+/// \brief Read finished data
+///
+/// \param outq Pointer to an output queue
+/// \param out Beginning of the output buffer
+/// \param out_pos The next byte will be written to
+/// out[*out_pos].
+/// \param out_size Size of the out buffer; the first byte into
+/// which no data is written to is out[out_size].
+/// \param unpadded_size Unpadded Size from the Block encoder
+/// \param uncompressed_size Uncompressed Size from the Block encoder
+///
+/// \return - LZMA: All OK. Either no data was available or the buffer
+/// being read didn't become empty yet.
+/// - LZMA_STREAM_END: The buffer being read was finished.
+/// *unpadded_size and *uncompressed_size were set.
+///
+/// \note This reads lzma_outbuf.finished variables and thus call
+/// to this function needs to be protected with a mutex.
+///
+extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,
+ uint8_t *restrict out, size_t *restrict out_pos,
+ size_t out_size, lzma_vli *restrict unpadded_size,
+ lzma_vli *restrict uncompressed_size);
+
+
+/// \brief Test if there is at least one buffer free
+///
+/// This must be used before getting a new buffer with lzma_outq_get_buf().
+///
+static inline bool
+lzma_outq_has_buf(const lzma_outq *outq)
+{
+ return outq->bufs_used < outq->bufs_allocated;
+}
+
+
+/// \brief Test if the queue is completely empty
+static inline bool
+lzma_outq_is_empty(const lzma_outq *outq)
+{
+ return outq->bufs_used == 0;
+}
diff --git a/src/liblzma/common/stream_encoder_mt.c b/src/liblzma/common/stream_encoder_mt.c
new file mode 100644
index 0000000..a4b2800
--- /dev/null
+++ b/src/liblzma/common/stream_encoder_mt.c
@@ -0,0 +1,1013 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+/// \file stream_encoder_mt.c
+/// \brief Multithreaded .xz Stream encoder
+//
+// Author: Lasse Collin
+//
+// This file has been put into the public domain.
+// You can do whatever you want with this file.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "filter_encoder.h"
+#include "easy_preset.h"
+#include "block_encoder.h"
+#include "index_encoder.h"
+#include "outqueue.h"
+
+
+/// Maximum supported block size. This makes it simpler to prevent integer
+/// overflows if we are given unusually large block size.
+#define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)
+
+
+typedef enum {
+ /// Waiting for work.
+ THR_IDLE,
+
+ /// Encoding is in progress.
+ THR_RUN,
+
+ /// Encoding is in progress but no more input data will
+ /// be read.
+ THR_FINISH,
+
+ /// The main thread wants the thread to stop whatever it was doing
+ /// but not exit.
+ THR_STOP,
+
+ /// The main thread wants the thread to exit. We could use
+ /// cancellation but since there's stopped anyway, this is lazier.
+ THR_EXIT,
+
+} worker_state;
+
+
+typedef struct worker_thread_s worker_thread;
+struct worker_thread_s {
+ worker_state state;
+
+ /// Input buffer of coder->block_size bytes. The main thread will
+ /// put new input into this and update in_size accordingly. Once
+ /// no more input is coming, state will be set to THR_FINISH.
+ uint8_t *in;
+
+ /// Amount of data available in the input buffer. This is modified
+ /// only by the main thread.
+ size_t in_size;
+
+ /// Output buffer for this thread. This is set by the main
+ /// thread every time a new Block is started with this thread
+ /// structure.
+ lzma_outbuf *outbuf;
+
+ /// Pointer to the main structure is needed when putting this
+ /// thread back to the stack of free threads.
+ lzma_coder *coder;
+
+ /// The allocator is set by the main thread. Since a copy of the
+ /// pointer is kept here, the application must not change the
+ /// allocator before calling lzma_end().
+ lzma_allocator *allocator;
+
+ /// Block encoder
+ lzma_next_coder block_encoder;
+
+ /// Compression options for this Block
+ lzma_block block_options;
+
+ /// Next structure in the stack of free worker threads.
+ worker_thread *next;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+
+ /// The ID of this thread is used to join the thread
+ /// when it's not needed anymore.
+ pthread_t thread_id;
+};
+
+
+struct lzma_coder_s {
+ enum {
+ SEQ_STREAM_HEADER,
+ SEQ_BLOCK,
+ SEQ_INDEX,
+ SEQ_STREAM_FOOTER,
+ } sequence;
+
+ /// Start a new Block every block_size bytes of input unless
+ /// LZMA_FULL_FLUSH or LZMA_FULL_BARRIER is used earlier.
+ size_t block_size;
+
+ /// The filter chain currently in use
+ lzma_filter filters[LZMA_FILTERS_MAX + 1];
+
+
+ /// Index to hold sizes of the Blocks
+ lzma_index *index;
+
+ /// Index encoder
+ lzma_next_coder index_encoder;
+
+
+ /// Stream Flags for encoding the Stream Header and Stream Footer.
+ lzma_stream_flags stream_flags;
+
+ /// Buffer to hold Stream Header and Stream Footer.
+ uint8_t header[LZMA_STREAM_HEADER_SIZE];
+
+ /// Read position in header[]
+ size_t header_pos;
+
+
+ /// Output buffer queue for compressed data
+ lzma_outq outq;
+
+
+ /// True if wait_max is used.
+ bool has_timeout;
+
+ /// Maximum wait time if cannot use all the input and cannot
+ /// fill the output buffer.
+ struct timespec wait_max;
+
+
+ /// Error code from a worker thread
+ lzma_ret thread_error;
+
+ /// Array of allocated thread-specific structures
+ worker_thread *threads;
+
+ /// Number of structures in "threads" above. This is also the
+ /// number of threads that will be created at maximum.
+ uint32_t threads_max;
+
+ /// Number of thread structures that have been initialized, and
+ /// thus the number of worker threads actually created so far.
+ uint32_t threads_initialized;
+
+ /// Stack of free threads. When a thread finishes, it puts itself
+ /// back into this stack. This starts as empty because threads
+ /// are created only when actually needed.
+ worker_thread *threads_free;
+
+ /// The most recent worker thread to which the main thread writes
+ /// the new input from the application.
+ worker_thread *thr;
+
+ pthread_mutex_t mutex;
+ mythread_cond cond;
+};
+
+
+/// Tell the main thread that something has gone wrong.
+static void
+worker_error(worker_thread *thr, lzma_ret ret)
+{
+ assert(ret != LZMA_OK);
+ assert(ret != LZMA_STREAM_END);
+
+ mythread_sync(thr->coder->mutex) {
+ if (thr->coder->thread_error == LZMA_OK)
+ thr->coder->thread_error = ret;
+
+ mythread_cond_signal(&thr->coder->cond);
+ }
+
+ return;
+}
+
+
+static worker_state
+worker_encode(worker_thread *thr, worker_state state)
+{
+ // Set the Block options.
+ thr->block_options = (lzma_block){
+ .version = 0,
+ .check = thr->coder->stream_flags.check,
+ .compressed_size = thr->coder->outq.buf_size_max,
+ .uncompressed_size = thr->coder->block_size,
+
+ // TODO: To allow changing the filter chain, the filters
+ // array must be copied to each worker_thread.
+ .filters = thr->coder->filters,
+ };
+
+ // Calculate maximum size of the Block Header. This amount is
+ // reserved in the beginning of the buffer so that Block Header
+ // along with Compressed Size and Uncompressed Size can be
+ // written there.
+ lzma_ret ret = lzma_block_header_size(&thr->block_options);
+ if (ret != LZMA_OK) {
+ worker_error(thr, ret);
+ return THR_STOP;
+ }
+
+ // Initialize the Block encoder.
+ ret = lzma_block_encoder_init(&thr->block_encoder,
+ thr->allocator, &thr->block_options);
+ if (ret != LZMA_OK) {
+ worker_error(thr, ret);
+ return THR_STOP;
+ }
+
+ size_t in_pos = 0;
+ size_t in_size = 0;
+
+ thr->outbuf->size = thr->block_options.header_size;
+ const size_t out_size = thr->coder->outq.buf_size_max;
+
+ do {
+ mythread_sync(thr->mutex) {
+ while (in_size == thr->in_size
+ && thr->state == THR_RUN)
+ pthread_cond_wait(&thr->cond, &thr->mutex);
+
+ state = thr->state;
+ in_size = thr->in_size;
+
+ // TODO? Store in_pos and out_pos into *thr here
+ // so that the application may read them via
+ // some currently non-existing function to get
+ // progress information.
+ }
+
+ // Return if we were asked to stop or exit.
+ if (state >= THR_STOP)
+ return state;
+
+ lzma_action action = state == THR_FINISH
+ ? LZMA_FINISH : LZMA_RUN;
+
+ // Limit the amount of input given to the Block encoder
+ // at once. This way this thread can react fairly quickly
+ // if the main thread wants us to stop or exit.
+ static const size_t in_chunk_max = 16384;
+ size_t in_limit = in_size;
+ if (in_size - in_pos > in_chunk_max) {
+ in_limit = in_pos + in_chunk_max;
+ action = LZMA_RUN;
+ }
+
+ ret = thr->block_encoder.code(
+ thr->block_encoder.coder, thr->allocator,
+ thr->in, &in_pos, in_limit, thr->outbuf->buf,
+ &thr->outbuf->size, out_size, action);
+ } while (ret == LZMA_OK);
+
+ if (ret != LZMA_STREAM_END) {
+ worker_error(thr, ret);
+ return THR_STOP;
+ }
+
+ assert(state == THR_FINISH);
+
+ // Encode the Block Header. By doing it after the compression,
+ // we can store the Compressed Size and Uncompressed Size fields.
+ ret = lzma_block_header_encode(&thr->block_options, thr->outbuf->buf);
+ if (ret != LZMA_OK) {
+ worker_error(thr, ret);
+ return THR_STOP;
+ }
+
+ // Set the size information that will be read by the main thread
+ // to write the Index field.
+ thr->outbuf->unpadded_size
+ = lzma_block_unpadded_size(&thr->block_options);
+ assert(thr->outbuf->unpadded_size != 0);
+ thr->outbuf->uncompressed_size = thr->block_options.uncompressed_size;
+
+ return THR_FINISH;
+}
+
+
+static void *
+worker_start(void *thr_ptr)
+{
+ worker_thread *thr = thr_ptr;
+ worker_state state = THR_IDLE; // Init to silence a warning
+
+ while (true) {
+ // Wait for work.
+ mythread_sync(thr->mutex) {
+ while (true) {
+ // The thread is already idle so if we are
+ // requested to stop, just set the state.
+ if (thr->state == THR_STOP) {
+ thr->state = THR_IDLE;
+ pthread_cond_signal(&thr->cond);
+ }
+
+ state = thr->state;
+ if (state != THR_IDLE)
+ break;
+
+ pthread_cond_wait(&thr->cond, &thr->mutex);
+ }
+ }
+
+ assert(state != THR_IDLE);
+ assert(state != THR_STOP);
+
+ if (state <= THR_FINISH)
+ state = worker_encode(thr, state);
+
+ if (state == THR_EXIT)
+ break;
+
+ // Mark the thread as idle. Signal is needed for the case
+ // where the main thread is waiting for the threads to stop.
+ mythread_sync(thr->mutex) {
+ thr->state = THR_IDLE;
+ pthread_cond_signal(&thr->cond);
+ }
+
+ mythread_sync(thr->coder->mutex) {
+ // Mark the output buffer as finished if
+ // no errors occurred.
+ thr->outbuf->finished = state == THR_FINISH;
+
+ // Return this thread to the stack of free threads.
+ thr->next = thr->coder->threads_free;
+ thr->coder->threads_free = thr;
+
+ mythread_cond_signal(&thr->coder->cond);
+ }
+ }
+
+ // Exiting, free the resources.
+ pthread_mutex_destroy(&thr->mutex);
+ pthread_cond_destroy(&thr->cond);
+
+ lzma_next_end(&thr->block_encoder, thr->allocator);
+ lzma_free(thr->in, thr->allocator);
+ return NULL;
+}
+
+
+/// Make the threads stop but not exit. Optionally wait for them to stop.
+static void
+threads_stop(lzma_coder *coder, bool wait)
+{
+ // Tell the threads to stop.
+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+ mythread_sync(coder->threads[i].mutex) {
+ coder->threads[i].state = THR_STOP;
+ pthread_cond_signal(&coder->threads[i].cond);
+ }
+ }
+
+ if (!wait)
+ return;
+
+ // Wait for the threads to settle in the idle state.
+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+ mythread_sync(coder->threads[i].mutex) {
+ while (coder->threads[i].state != THR_IDLE)
+ pthread_cond_wait(&coder->threads[i].cond,
+ &coder->threads[i].mutex);
+ }
+ }
+
+ return;
+}
+
+
+/// Stop the threads and free the resources associated with them.
+/// Wait until the threads have exited.
+static void
+threads_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+ mythread_sync(coder->threads[i].mutex) {
+ coder->threads[i].state = THR_EXIT;
+ pthread_cond_signal(&coder->threads[i].cond);
+ }
+ }
+
+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
+ int ret = pthread_join(coder->threads[i].thread_id, NULL);
+ assert(ret == 0);
+ (void)ret;
+ }
+
+ lzma_free(coder->threads, allocator);
+ return;
+}
+
+
+/// Initialize a new worker_thread structure and create a new thread.
+static lzma_ret
+initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
+{
+ worker_thread *thr = &coder->threads[coder->threads_initialized];
+
+ thr->in = lzma_alloc(coder->block_size, allocator);
+ if (thr->in == NULL)
+ return LZMA_MEM_ERROR;
+
+ if (pthread_mutex_init(&thr->mutex, NULL))
+ goto error_mutex;
+
+ if (pthread_cond_init(&thr->cond, NULL))
+ goto error_cond;
+
+ thr->state = THR_IDLE;
+ thr->allocator = allocator;
+ thr->coder = coder;
+ thr->block_encoder = LZMA_NEXT_CODER_INIT;
+
+ if (mythread_create(&thr->thread_id, &worker_start, thr))
+ goto error_thread;
+
+ ++coder->threads_initialized;
+ coder->thr = thr;
+
+ return LZMA_OK;
+
+error_thread:
+ pthread_cond_destroy(&thr->cond);
+
+error_cond:
+ pthread_mutex_destroy(&thr->mutex);
+
+error_mutex:
+ lzma_free(thr->in, allocator);
+ return LZMA_MEM_ERROR;
+}
+
+
+static lzma_ret
+get_thread(lzma_coder *coder, lzma_allocator *allocator)
+{
+ // If there are no free output subqueues, there is no
+ // point to try getting a thread.
+ if (!lzma_outq_has_buf(&coder->outq))
+ return LZMA_OK;
+
+ // If there is a free structure on the stack, use it.
+ mythread_sync(coder->mutex) {
+ if (coder->threads_free != NULL) {
+ coder->thr = coder->threads_free;
+ coder->threads_free = coder->threads_free->next;
+ }
+ }
+
+ if (coder->thr == NULL) {
+ // If there are no uninitialized structures left, return.
+ if (coder->threads_initialized == coder->threads_max)
+ return LZMA_OK;
+
+ // Initialize a new thread.
+ return_if_error(initialize_new_thread(coder, allocator));
+ }
+
+ // Reset the parts of the thread state that have to be done
+ // in the main thread.
+ mythread_sync(coder->thr->mutex) {
+ coder->thr->state = THR_RUN;
+ coder->thr->in_size = 0;
+ coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);
+ pthread_cond_signal(&coder->thr->cond);
+ }
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *restrict in, size_t *restrict in_pos,
+ size_t in_size, lzma_action action)
+{
+ while (*in_pos < in_size
+ || (coder->thr != NULL && action != LZMA_RUN)) {
+ if (coder->thr == NULL) {
+ // Get a new thread.
+ const lzma_ret ret = get_thread(coder, allocator);
+ if (coder->thr == NULL)
+ return ret;
+ }
+
+ // Copy the input data to thread's buffer.
+ size_t thr_in_size = coder->thr->in_size;
+ lzma_bufcpy(in, in_pos, in_size, coder->thr->in,
+ &thr_in_size, coder->block_size);
+
+ // Tell the Block encoder to finish if
+ // - it has got block_size bytes of input; or
+ // - all input was used and LZMA_FINISH, LZMA_FULL_FLUSH,
+ // or LZMA_FULL_BARRIER was used.
+ //
+ // TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
+ const bool finish = thr_in_size == coder->block_size
+ || (*in_pos == in_size && action != LZMA_RUN);
+
+ bool block_error = false;
+
+ mythread_sync(coder->thr->mutex) {
+ if (coder->thr->state == THR_IDLE) {
+ // Something has gone wrong with the Block
+ // encoder. It has set coder->thread_error
+ // which we will read a few lines later.
+ block_error = true;
+ } else {
+ // Tell the Block encoder its new amount
+ // of input and update the state if needed.
+ coder->thr->in_size = thr_in_size;
+
+ if (finish)
+ coder->thr->state = THR_FINISH;
+
+ pthread_cond_signal(&coder->thr->cond);
+ }
+ }
+
+ if (block_error) {
+ lzma_ret ret;
+
+ mythread_sync(coder->mutex) {
+ ret = coder->thread_error;
+ }
+
+ return ret;
+ }
+
+ if (finish)
+ coder->thr = NULL;
+ }
+
+ return LZMA_OK;
+}
+
+
+/// Wait until more input can be consumed, more output can be read, or
+/// an optional timeout is reached.
+static bool
+wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
+ bool *has_blocked, bool has_input)
+{
+ if (coder->has_timeout && !*has_blocked) {
+ // Every time when stream_encode_mt() is called via
+ // lzma_code(), *has_block starts as false. We set it
+ // to true here and calculate the absolute time when
+ // we must return if there's nothing to do.
+ //
+ // The idea of *has_blocked is to avoid unneeded calls
+ // to mythread_cond_abstime(), which may do a syscall
+ // depending on the operating system.
+ *has_blocked = true;
+ *wait_abs = coder->wait_max;
+ mythread_cond_abstime(&coder->cond, wait_abs);
+ }
+
+ bool timed_out = false;
+
+ mythread_sync(coder->mutex) {
+ // There are four things that we wait. If one of them
+ // becomes possible, we return.
+ // - If there is input left, we need to get a free
+ // worker thread and an output buffer for it.
+ // - Data ready to be read from the output queue.
+ // - A worker thread indicates an error.
+ // - Time out occurs.
+ while ((!has_input || coder->threads_free == NULL
+ || !lzma_outq_has_buf(&coder->outq))
+ && !lzma_outq_is_readable(&coder->outq)
+ && coder->thread_error == LZMA_OK
+ && !timed_out) {
+ if (coder->has_timeout)
+ timed_out = mythread_cond_timedwait(
+ &coder->cond, &coder->mutex,
+ wait_abs) != 0;
+ else
+ mythread_cond_wait(&coder->cond,
+ &coder->mutex);
+ }
+ }
+
+ return timed_out;
+}
+
+
+static lzma_ret
+stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
+ const uint8_t *restrict in, size_t *restrict in_pos,
+ size_t in_size, uint8_t *restrict out,
+ size_t *restrict out_pos, size_t out_size, lzma_action action)
+{
+ switch (coder->sequence) {
+ case SEQ_STREAM_HEADER:
+ lzma_bufcpy(coder->header, &coder->header_pos,
+ sizeof(coder->header),
+ out, out_pos, out_size);
+ if (coder->header_pos < sizeof(coder->header))
+ return LZMA_OK;
+
+ coder->header_pos = 0;
+ coder->sequence = SEQ_BLOCK;
+
+ // Fall through
+
+ case SEQ_BLOCK: {
+ // Initialized to silence warnings.
+ lzma_vli unpadded_size = 0;
+ lzma_vli uncompressed_size = 0;
+ lzma_ret ret = LZMA_OK;
+
+ // These are for wait_for_work().
+ bool has_blocked = false;
+ struct timespec wait_abs;
+
+ while (true) {
+ mythread_sync(coder->mutex) {
+ // Check for Block encoder errors.
+ ret = coder->thread_error;
+ if (ret != LZMA_OK) {
+ assert(ret != LZMA_STREAM_END);
+ break;
+ }
+
+ // Try to read compressed data to out[].
+ ret = lzma_outq_read(&coder->outq,
+ out, out_pos, out_size,
+ &unpadded_size,
+ &uncompressed_size);
+ }
+
+ if (ret == LZMA_STREAM_END) {
+ // End of Block. Add it to the Index.
+ ret = lzma_index_append(coder->index,
+ allocator, unpadded_size,
+ uncompressed_size);
+
+ // If we didn't fill the output buffer yet,
+ // try to read more data. Maybe the next
+ // outbuf has been finished already too.
+ if (*out_pos < out_size)
+ continue;
+ }
+
+ if (ret != LZMA_OK) {
+ // coder->thread_error was set or
+ // lzma_index_append() failed.
+ threads_stop(coder, false);
+ return ret;
+ }
+
+ // Check if the last Block was finished.
+ if (action == LZMA_FINISH
+ && *in_pos == in_size
+ && lzma_outq_is_empty(
+ &coder->outq))
+ break;
+
+ // Try to give uncompressed data to a worker thread.
+ ret = stream_encode_in(coder, allocator,
+ in, in_pos, in_size, action);
+ if (ret != LZMA_OK) {
+ threads_stop(coder, false);
+ return ret;
+ }
+
+ // Return if
+ // - we have used all the input and expect to
+ // get more input; or
+ // - the output buffer has been filled.
+ //
+ // TODO: Support flushing.
+ if ((*in_pos == in_size && action != LZMA_FINISH)
+ || *out_pos == out_size)
+ return LZMA_OK;
+
+ // Neither in nor out has been used completely.
+ // Wait until there's something we can do.
+ if (wait_for_work(coder, &wait_abs, &has_blocked,
+ *in_pos < in_size))
+ return LZMA_TIMED_OUT;
+ }
+
+ // All Blocks have been encoded and the threads have stopped.
+ // Prepare to encode the Index field.
+ return_if_error(lzma_index_encoder_init(
+ &coder->index_encoder, allocator,
+ coder->index));
+ coder->sequence = SEQ_INDEX;
+ }
+
+ // Fall through
+
+ case SEQ_INDEX: {
+ // Call the Index encoder. It doesn't take any input, so
+ // those pointers can be NULL.
+ const lzma_ret ret = coder->index_encoder.code(
+ coder->index_encoder.coder, allocator,
+ NULL, NULL, 0,
+ out, out_pos, out_size, LZMA_RUN);
+ if (ret != LZMA_STREAM_END)
+ return ret;
+
+ // Encode the Stream Footer into coder->buffer.
+ coder->stream_flags.backward_size
+ = lzma_index_size(coder->index);
+ if (lzma_stream_footer_encode(&coder->stream_flags,
+ coder->header) != LZMA_OK)
+ return LZMA_PROG_ERROR;
+
+ coder->sequence = SEQ_STREAM_FOOTER;
+ }
+
+ // Fall through
+
+ case SEQ_STREAM_FOOTER:
+ lzma_bufcpy(coder->header, &coder->header_pos,
+ sizeof(coder->header),
+ out, out_pos, out_size);
+ return coder->header_pos < sizeof(coder->header)
+ ? LZMA_OK : LZMA_STREAM_END;
+ }
+
+ assert(0);
+ return LZMA_PROG_ERROR;
+}
+
+
+static void
+stream_encoder_mt_end(lzma_coder *coder, lzma_allocator *allocator)
+{
+ // Threads must be killed before the output queue can be freed.
+ threads_end(coder, allocator);
+ lzma_outq_end(&coder->outq, allocator);
+
+ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+ lzma_free(coder->filters[i].options, allocator);
+
+ lzma_next_end(&coder->index_encoder, allocator);
+ lzma_index_end(coder->index, allocator);
+
+ mythread_cond_destroy(&coder->cond);
+ pthread_mutex_destroy(&coder->mutex);
+
+ lzma_free(coder, allocator);
+ return;
+}
+
+
+/// Options handling for lzma_stream_encoder_mt_init() and
+/// lzma_stream_encoder_mt_memusage()
+static lzma_ret
+get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
+ const lzma_filter **filters, uint64_t *block_size,
+ uint64_t *outbuf_size_max)
+{
+ // Validate some of the options.
+ if (options == NULL)
+ return LZMA_PROG_ERROR;
+
+ if (options->flags != 0 || options->threads == 0
+ || options->threads > LZMA_THREADS_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ if (options->filters != NULL) {
+ // Filter chain was given, use it as is.
+ *filters = options->filters;
+ } else {
+ // Use a preset.
+ if (lzma_easy_preset(opt_easy, options->preset))
+ return LZMA_OPTIONS_ERROR;
+
+ *filters = opt_easy->filters;
+ }
+
+ // Block size
+ if (options->block_size > 0) {
+ if (options->block_size > BLOCK_SIZE_MAX)
+ return LZMA_OPTIONS_ERROR;
+
+ *block_size = options->block_size;
+ } else {
+ // Determine the Block size from the filter chain.
+ *block_size = lzma_mt_block_size(*filters);
+ if (*block_size == 0)
+ return LZMA_OPTIONS_ERROR;
+
+ assert(*block_size <= BLOCK_SIZE_MAX);
+ }
+
+ // Calculate the maximum amount output that a single output buffer
+ // may need to hold. This is the same as the maximum total size of
+ // a Block.
+ //
+ // FIXME: As long as the encoder keeps the whole input buffer
+ // available and doesn't start writing output before finishing
+ // the Block, it could use lzma_stream_buffer_bound() and use
+ // uncompressed LZMA2 chunks if the data doesn't compress.
+ *outbuf_size_max = *block_size + *block_size / 16 + 16384;
+
+ return LZMA_OK;
+}
+
+
+static lzma_ret
+stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
+ const lzma_mt *options)
+{
+ lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);
+
+ // Get the filter chain.
+ lzma_options_easy easy;
+ const lzma_filter *filters;
+ uint64_t block_size;
+ uint64_t outbuf_size_max;
+ return_if_error(get_options(options, &easy, &filters,
+ &block_size, &outbuf_size_max));
+
+#if SIZE_MAX < UINT64_MAX
+ if (block_size > SIZE_MAX)
+ return LZMA_MEM_ERROR;
+#endif
+
+ // FIXME TODO: Validate the filter chain so that we can give
+ // an error in this function instead of delaying it to the first
+ // call to lzma_code().
+
+ // Validate the Check ID.
+ if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
+ return LZMA_PROG_ERROR;
+
+ if (!lzma_check_is_supported(options->check))
+ return LZMA_UNSUPPORTED_CHECK;
+
+ // Allocate and initialize the base structure if needed.
+ if (next->coder == NULL) {
+ next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
+ if (next->coder == NULL)
+ return LZMA_MEM_ERROR;
+
+ // For the mutex and condition variable initializations
+ // the error handling has to be done here because
+ // stream_encoder_mt_end() doesn't know if they have
+ // already been initialized or not.
+ if (pthread_mutex_init(&next->coder->mutex, NULL)) {
+ lzma_free(next->coder, allocator);
+ next->coder = NULL;
+ return LZMA_MEM_ERROR;
+ }
+
+ if (mythread_cond_init(&next->coder->cond)) {
+ pthread_mutex_destroy(&next->coder->mutex);
+ lzma_free(next->coder, allocator);
+ next->coder = NULL;
+ return LZMA_MEM_ERROR;
+ }
+
+ next->code = &stream_encode_mt;
+ next->end = &stream_encoder_mt_end;
+// next->update = &stream_encoder_mt_update;
+
+ next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
+ next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
+ next->coder->index = NULL;
+ memzero(&next->coder->outq, sizeof(next->coder->outq));
+ next->coder->threads = NULL;
+ next->coder->threads_max = 0;
+ next->coder->threads_initialized = 0;
+ }
+
+ // Basic initializations
+ next->coder->sequence = SEQ_STREAM_HEADER;
+ next->coder->block_size = (size_t)(block_size);
+ next->coder->thread_error = LZMA_OK;
+ next->coder->thr = NULL;
+
+ // Allocate the thread-specific base structures.
+ assert(options->threads > 0);
+ if (next->coder->threads_max != options->threads) {
+ threads_end(next->coder, allocator);
+
+ next->coder->threads = NULL;
+ next->coder->threads_max = 0;
+
+ next->coder->threads_initialized = 0;
+ next->coder->threads_free = NULL;
+
+ next->coder->threads = lzma_alloc(
+ options->threads * sizeof(worker_thread),
+ allocator);
+ if (next->coder->threads == NULL)
+ return LZMA_MEM_ERROR;
+
+ next->coder->threads_max = options->threads;
+ } else {
+ // Reuse the old structures and threads. Tell the running
+ // threads to stop and wait until they have stopped.
+ threads_stop(next->coder, true);
+ }
+
+ // Output queue
+ return_if_error(lzma_outq_init(&next->coder->outq, allocator,
+ outbuf_size_max, options->threads));
+
+ // Timeout
+ if (options->timeout > 0) {
+ next->coder->wait_max.tv_sec = options->timeout / 1000;
+ next->coder->wait_max.tv_nsec
+ = (options->timeout % 1000) * 1000000L;
+ next->coder->has_timeout = true;
+ } else {
+ next->coder->has_timeout = false;
+ }
+
+ // Free the old filter chain and copy the new one.
+ for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
+ lzma_free(next->coder->filters[i].options, allocator);
+
+ return_if_error(lzma_filters_copy(options->filters,
+ next->coder->filters, allocator));
+
+ // Index
+ lzma_index_end(next->coder->index, allocator);
+ next->coder->index = lzma_index_init(allocator);
+ if (next->coder->index == NULL)
+ return LZMA_MEM_ERROR;
+
+ // Stream Header
+ next->coder->stream_flags.version = 0;
+ next->coder->stream_flags.check = options->check;
+ return_if_error(lzma_stream_header_encode(
+ &next->coder->stream_flags, next->coder->header));
+
+ next->coder->header_pos = 0;
+
+ return LZMA_OK;
+}
+
+
+extern LZMA_API(lzma_ret)
+lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)
+{
+ lzma_next_strm_init(stream_encoder_mt_init, strm, options);
+
+ strm->internal->supported_actions[LZMA_RUN] = true;
+// strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
+// strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
+// strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
+ strm->internal->supported_actions[LZMA_FINISH] = true;
+
+ return LZMA_OK;
+}
+
+
+// This function name is a monster but it's consistent with the older
+// monster names. :-( 31 chars is the max that C99 requires so in that
+// sense it's not too long. ;-)
+extern LZMA_API(uint64_t)
+lzma_stream_encoder_mt_memusage(const lzma_mt *options)
+{
+ lzma_options_easy easy;
+ const lzma_filter *filters;
+ uint64_t block_size;
+ uint64_t outbuf_size_max;
+
+ if (get_options(options, &easy, &filters, &block_size,
+ &outbuf_size_max) != LZMA_OK)
+ return UINT64_MAX;
+
+ // Memory usage of the input buffers
+ const uint64_t inbuf_memusage = options->threads * block_size;
+
+ // Memory usage of the filter encoders
+ uint64_t filters_memusage
+ = lzma_raw_encoder_memusage(options->filters);
+ if (filters_memusage == UINT64_MAX)
+ return UINT64_MAX;
+
+ filters_memusage *= options->threads;
+
+ // Memory usage of the output queue
+ const uint64_t outq_memusage = lzma_outq_memusage(
+ outbuf_size_max, options->threads);
+ if (outq_memusage == UINT64_MAX)
+ return UINT64_MAX;
+
+ // Sum them with overflow checking.
+ uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
+ + options->threads * sizeof(worker_thread);
+
+ if (UINT64_MAX - total_memusage < inbuf_memusage)
+ return UINT64_MAX;
+
+ total_memusage += inbuf_memusage;
+
+ if (UINT64_MAX - total_memusage < filters_memusage)
+ return UINT64_MAX;
+
+ total_memusage += filters_memusage;
+
+ if (UINT64_MAX - total_memusage < outq_memusage)
+ return UINT64_MAX;
+
+ return total_memusage + outq_memusage;
+}
diff --git a/src/liblzma/liblzma.map b/src/liblzma/liblzma.map
index 47a7c22..6dd4288 100644
--- a/src/liblzma/liblzma.map
+++ b/src/liblzma/liblzma.map
@@ -93,7 +93,13 @@
lzma_vli_decode;
lzma_vli_encode;
lzma_vli_size;
+};
+
+XZ_5.1.2alpha {
+global:
+ lzma_stream_encoder_mt;
+ lzma_stream_encoder_mt_memusage;
local:
*;
-};
+} XZ_5.0;
diff --git a/src/liblzma/validate_map.sh b/src/liblzma/validate_map.sh
deleted file mode 100644
index 3aee466..0000000
--- a/src/liblzma/validate_map.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-
-###############################################################################
-#
-# Check liblzma.map for certain types of errors
-#
-# Author: Lasse Collin
-#
-# This file has been put into the public domain.
-# You can do whatever you want with this file.
-#
-###############################################################################
-
-LC_ALL=C
-export LC_ALL
-
-STATUS=0
-
-cd "$(dirname "$0")"
-
-# Get the list of symbols that aren't defined in liblzma.map.
-SYMS=$(sed -n 's/^extern LZMA_API([^)]*) \([a-z0-9_]*\)(.*$/\1;/p' \
- api/lzma/*.h \
- | sort \
- | grep -Fve "$(sed '/[{}:*]/d;/^$/d;s/^ //' liblzma.map)")
-
-# Check that there are no old alpha or beta versions listed.
-VER=$(cd ../.. && sh build-aux/version.sh)
-NAMES=
-case $VER in
- *alpha | *beta)
- NAMES=$(sed -n 's/^.*XZ_\([^ ]*\)\(alpha\|beta\) .*$/\1\2/p' \
- liblzma.map | grep -Fv "$VER")
- ;;
-esac
-
-# Check for duplicate lines. It can catch missing dependencies.
-DUPS=$(sort liblzma.map | sed '/^$/d;/^global:$/d' | uniq -d)
-
-# Print error messages if needed.
-if test -n "$SYMS$NAMES$DUPS"; then
- echo
- echo 'validate_map.sh found problems from liblzma.map:'
- echo
-
- if test -n "$SYMS"; then
- echo 'liblzma.map lacks the following symbols:'
- echo "$SYMS"
- echo
- fi
-
- if test -n "$NAMES"; then
- echo 'Obsolete alpha or beta version names:'
- echo "$NAMES"
- echo
- fi
-
- if test -n "$DUPS"; then
- echo 'Duplicate lines:'
- echo "$DUPS"
- echo
- fi
-
- STATUS=1
-fi
-
-# Exit status is 1 if problems were found, 0 otherwise.
-exit "$STATUS"
diff --git a/src/xz/args.c b/src/xz/args.c
index 1b88c1e..9a4f82b 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -55,6 +55,67 @@
static void
+parse_block_list(char *str)
+{
+ // It must be non-empty and not begin with a comma.
+ if (str[0] == '\0' || str[0] == ',')
+ message_fatal(_("%s: Invalid argument to --block-list"), str);
+
+ // Count the number of comma-separated strings.
+ size_t count = 1;
+ for (size_t i = 0; str[i] != '\0'; ++i)
+ if (str[i] == ',')
+ ++count;
+
+ // Prevent an unlikely integer overflow.
+ if (count > SIZE_MAX / sizeof(uint64_t) - 1)
+ message_fatal(_("%s: Too many arguments to --block-list"),
+ str);
+
+ // Allocate memory to hold all the sizes specified.
+ // If --block-list was specified already, its value is forgotten.
+ free(opt_block_list);
+ opt_block_list = xmalloc((count + 1) * sizeof(uint64_t));
+
+ for (size_t i = 0; i < count; ++i) {
+ // Locate the next comma and replace it with \0.
+ char *p = strchr(str, ',');
+ if (p != NULL)
+ *p = '\0';
+
+ if (str[0] == '\0') {
+ // There is no string, that is, a comma follows
+ // another comma. Use the previous value.
+ //
+ // NOTE: We checked earler that the first char
+ // of the whole list cannot be a comma.
+ assert(i > 0);
+ opt_block_list[i] = opt_block_list[i - 1];
+ } else {
+ opt_block_list[i] = str_to_uint64("block-list", str,
+ 0, UINT64_MAX);
+
+ // Zero indicates no more new Blocks.
+ if (opt_block_list[i] == 0) {
+ if (i + 1 != count)
+ message_fatal(_("0 can only be used "
+ "as the last element "
+ "in --block-list"));
+
+ opt_block_list[i] = UINT64_MAX;
+ }
+ }
+
+ str = p + 1;
+ }
+
+ // Terminate the array.
+ opt_block_list[count] = 0;
+ return;
+}
+
+
+static void
parse_real(args_info *args, int argc, char **argv)
{
enum {
@@ -73,6 +134,7 @@
OPT_FILES,
OPT_FILES0,
OPT_BLOCK_SIZE,
+ OPT_BLOCK_LIST,
OPT_MEM_COMPRESS,
OPT_MEM_DECOMPRESS,
OPT_NO_ADJUST,
@@ -107,6 +169,7 @@
{ "format", required_argument, NULL, 'F' },
{ "check", required_argument, NULL, 'C' },
{ "block-size", required_argument, NULL, OPT_BLOCK_SIZE },
+ { "block-list", required_argument, NULL, OPT_BLOCK_LIST },
{ "memlimit-compress", required_argument, NULL, OPT_MEM_COMPRESS },
{ "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS },
{ "memlimit", required_argument, NULL, 'M' },
@@ -179,8 +242,9 @@
break;
case 'T':
- hardware_threadlimit_set(str_to_uint64(
- "threads", optarg, 0, UINT32_MAX));
+ // The max is from src/liblzma/common/common.h.
+ hardware_threads_set(str_to_uint64("threads",
+ optarg, 0, 16384));
break;
// --version
@@ -377,6 +441,11 @@
0, LZMA_VLI_MAX);
break;
+ case OPT_BLOCK_LIST: {
+ parse_block_list(optarg);
+ break;
+ }
+
case OPT_SINGLE_STREAM:
opt_single_stream = true;
break;
@@ -589,3 +658,13 @@
return;
}
+
+
+#ifndef NDEBUG
+extern void
+args_free(void)
+{
+ free(opt_block_list);
+ return;
+}
+#endif
diff --git a/src/xz/args.h b/src/xz/args.h
index b23f4ef..53c4a98 100644
--- a/src/xz/args.h
+++ b/src/xz/args.h
@@ -40,3 +40,4 @@
extern const char stdin_filename[];
extern void args_parse(args_info *args, int argc, char **argv);
+extern void args_free(void);
diff --git a/src/xz/coder.c b/src/xz/coder.c
index a3366d0..a98be97 100644
--- a/src/xz/coder.c
+++ b/src/xz/coder.c
@@ -26,6 +26,7 @@
bool opt_auto_adjust = true;
bool opt_single_stream = false;
uint64_t opt_block_size = 0;
+uint64_t *opt_block_list = NULL;
/// Stream used to communicate with liblzma
@@ -55,6 +56,14 @@
/// This becomes false if the --check=CHECK option is used.
static bool check_default = true;
+#ifdef HAVE_PTHREAD
+static lzma_mt mt_options = {
+ .flags = 0,
+ .timeout = 300,
+ .filters = filters,
+};
+#endif
+
extern void
coder_set_check(lzma_check new_check)
@@ -117,6 +126,15 @@
extern void
coder_set_compression_settings(void)
{
+ // The default check type is CRC64, but fallback to CRC32
+ // if CRC64 isn't supported by the copy of liblzma we are
+ // using. CRC32 is always supported.
+ if (check_default) {
+ check = LZMA_CHECK_CRC64;
+ if (!lzma_check_is_supported(check))
+ check = LZMA_CHECK_CRC32;
+ }
+
// Options for LZMA1 or LZMA2 in case we are using a preset.
static lzma_options_lzma opt_lzma;
@@ -170,15 +188,30 @@
// Print the selected filter chain.
message_filters_show(V_DEBUG, filters);
- // If using --format=raw, we can be decoding. The memusage function
- // also validates the filter chain and the options used for the
- // filters.
+ // Get the memory usage. Note that if --format=raw was used,
+ // we can be decompressing.
const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
uint64_t memory_usage;
- if (opt_mode == MODE_COMPRESS)
- memory_usage = lzma_raw_encoder_memusage(filters);
- else
+ if (opt_mode == MODE_COMPRESS) {
+#ifdef HAVE_PTHREAD
+ if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
+ mt_options.threads = hardware_threads_get();
+ mt_options.block_size = opt_block_size;
+ mt_options.check = check;
+ memory_usage = lzma_stream_encoder_mt_memusage(
+ &mt_options);
+ if (memory_usage != UINT64_MAX)
+ message(V_DEBUG, _("Using up to %" PRIu32
+ " threads."),
+ mt_options.threads);
+ } else
+#endif
+ {
+ memory_usage = lzma_raw_encoder_memusage(filters);
+ }
+ } else {
memory_usage = lzma_raw_decoder_memusage(filters);
+ }
if (memory_usage == UINT64_MAX)
message_fatal(_("Unsupported filter chain or filter options"));
@@ -194,90 +227,99 @@
round_up_to_mib(decmem), 0));
}
- if (memory_usage > memory_limit) {
- // If --no-auto-adjust was used or we didn't find LZMA1 or
- // LZMA2 as the last filter, give an error immediately.
- // --format=raw implies --no-auto-adjust.
- if (!opt_auto_adjust || opt_format == FORMAT_RAW)
- memlimit_too_small(memory_usage);
+ if (memory_usage <= memory_limit)
+ return;
- assert(opt_mode == MODE_COMPRESS);
+ // If --no-auto-adjust was used or we didn't find LZMA1 or
+ // LZMA2 as the last filter, give an error immediately.
+ // --format=raw implies --no-auto-adjust.
+ if (!opt_auto_adjust || opt_format == FORMAT_RAW)
+ memlimit_too_small(memory_usage);
- // Look for the last filter if it is LZMA2 or LZMA1, so
- // we can make it use less RAM. With other filters we don't
- // know what to do.
- size_t i = 0;
- while (filters[i].id != LZMA_FILTER_LZMA2
- && filters[i].id != LZMA_FILTER_LZMA1) {
- if (filters[i].id == LZMA_VLI_UNKNOWN)
+ assert(opt_mode == MODE_COMPRESS);
+
+#ifdef HAVE_PTHREAD
+ if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
+ // Try to reduce the number of threads before
+ // adjusting the compression settings down.
+ do {
+ // FIXME? The real single-threaded mode has
+ // lower memory usage, but it's not comparable
+ // because it doesn't write the size info
+ // into Block Headers.
+ if (--mt_options.threads == 0)
memlimit_too_small(memory_usage);
- ++i;
- }
-
- // Decrease the dictionary size until we meet the memory
- // usage limit. First round down to full mebibytes.
- lzma_options_lzma *opt = filters[i].options;
- const uint32_t orig_dict_size = opt->dict_size;
- opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
- while (true) {
- // If it is below 1 MiB, auto-adjusting failed. We
- // could be more sophisticated and scale it down even
- // more, but let's see if many complain about this
- // version.
- //
- // FIXME: Displays the scaled memory usage instead
- // of the original.
- if (opt->dict_size < (UINT32_C(1) << 20))
- memlimit_too_small(memory_usage);
-
- memory_usage = lzma_raw_encoder_memusage(filters);
+ memory_usage = lzma_stream_encoder_mt_memusage(
+ &mt_options);
if (memory_usage == UINT64_MAX)
message_bug();
- // Accept it if it is low enough.
- if (memory_usage <= memory_limit)
- break;
+ } while (memory_usage > memory_limit);
- // Otherwise 1 MiB down and try again. I hope this
- // isn't too slow method for cases where the original
- // dict_size is very big.
- opt->dict_size -= UINT32_C(1) << 20;
- }
+ message(V_WARNING, _("Adjusted the number of threads "
+ "from %s to %s to not exceed "
+ "the memory usage limit of %s MiB"),
+ uint64_to_str(hardware_threads_get(), 0),
+ uint64_to_str(mt_options.threads, 1),
+ uint64_to_str(round_up_to_mib(
+ memory_limit), 2));
+ }
+#endif
- // Tell the user that we decreased the dictionary size.
- message(V_WARNING, _("Adjusted LZMA%c dictionary size "
- "from %s MiB to %s MiB to not exceed "
- "the memory usage limit of %s MiB"),
- filters[i].id == LZMA_FILTER_LZMA2
- ? '2' : '1',
- uint64_to_str(orig_dict_size >> 20, 0),
- uint64_to_str(opt->dict_size >> 20, 1),
- uint64_to_str(round_up_to_mib(
- memory_limit), 2));
+ if (memory_usage <= memory_limit)
+ return;
+
+ // Look for the last filter if it is LZMA2 or LZMA1, so we can make
+ // it use less RAM. With other filters we don't know what to do.
+ size_t i = 0;
+ while (filters[i].id != LZMA_FILTER_LZMA2
+ && filters[i].id != LZMA_FILTER_LZMA1) {
+ if (filters[i].id == LZMA_VLI_UNKNOWN)
+ memlimit_too_small(memory_usage);
+
+ ++i;
}
-/*
- // Limit the number of worker threads so that memory usage
- // limit isn't exceeded.
- assert(memory_usage > 0);
- size_t thread_limit = memory_limit / memory_usage;
- if (thread_limit == 0)
- thread_limit = 1;
+ // Decrease the dictionary size until we meet the memory
+ // usage limit. First round down to full mebibytes.
+ lzma_options_lzma *opt = filters[i].options;
+ const uint32_t orig_dict_size = opt->dict_size;
+ opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
+ while (true) {
+ // If it is below 1 MiB, auto-adjusting failed. We could be
+ // more sophisticated and scale it down even more, but let's
+ // see if many complain about this version.
+ //
+ // FIXME: Displays the scaled memory usage instead
+ // of the original.
+ if (opt->dict_size < (UINT32_C(1) << 20))
+ memlimit_too_small(memory_usage);
- if (opt_threads > thread_limit)
- opt_threads = thread_limit;
-*/
+ memory_usage = lzma_raw_encoder_memusage(filters);
+ if (memory_usage == UINT64_MAX)
+ message_bug();
- if (check_default) {
- // The default check type is CRC64, but fallback to CRC32
- // if CRC64 isn't supported by the copy of liblzma we are
- // using. CRC32 is always supported.
- check = LZMA_CHECK_CRC64;
- if (!lzma_check_is_supported(check))
- check = LZMA_CHECK_CRC32;
+ // Accept it if it is low enough.
+ if (memory_usage <= memory_limit)
+ break;
+
+ // Otherwise 1 MiB down and try again. I hope this
+ // isn't too slow method for cases where the original
+ // dict_size is very big.
+ opt->dict_size -= UINT32_C(1) << 20;
}
+ // Tell the user that we decreased the dictionary size.
+ message(V_WARNING, _("Adjusted LZMA%c dictionary size "
+ "from %s MiB to %s MiB to not exceed "
+ "the memory usage limit of %s MiB"),
+ filters[i].id == LZMA_FILTER_LZMA2
+ ? '2' : '1',
+ uint64_to_str(orig_dict_size >> 20, 0),
+ uint64_to_str(opt->dict_size >> 20, 1),
+ uint64_to_str(round_up_to_mib(memory_limit), 2));
+
return;
}
@@ -359,7 +401,14 @@
break;
case FORMAT_XZ:
- ret = lzma_stream_encoder(&strm, filters, check);
+#ifdef HAVE_PTHREAD
+ if (hardware_threads_get() > 1)
+ ret = lzma_stream_encoder_mt(
+ &strm, &mt_options);
+ else
+#endif
+ ret = lzma_stream_encoder(
+ &strm, filters, check);
break;
case FORMAT_LZMA:
@@ -474,15 +523,36 @@
// Assume that something goes wrong.
bool success = false;
- // block_remaining indicates how many input bytes to encode until
+ // block_remaining indicates how many input bytes to encode before
// finishing the current .xz Block. The Block size is set with
- // --block-size=SIZE. It has an effect only when compressing
- // to the .xz format. If block_remaining == UINT64_MAX, only
- // a single block is created.
+ // --block-size=SIZE and --block-list. They have an effect only when
+ // compressing to the .xz format. If block_remaining == UINT64_MAX,
+ // only a single block is created.
uint64_t block_remaining = UINT64_MAX;
- if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ
- && opt_block_size > 0)
- block_remaining = opt_block_size;
+
+ // Position in opt_block_list. Unused if --block-list wasn't used.
+ size_t list_pos = 0;
+
+ // Handle --block-size for single-threaded mode and the first step
+ // of --block-list.
+ if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_XZ) {
+ // --block-size doesn't do anything here in threaded mode,
+ // because the threaded encoder will take care of splitting
+ // to fixed-sized Blocks.
+ if (hardware_threads_get() == 1 && opt_block_size > 0)
+ block_remaining = opt_block_size;
+
+ // If --block-list was used, start with the first size.
+ //
+ // FIXME: Currently this overrides --block-size but this isn't
+ // good. For threaded case, we want --block-size to specify
+ // how big Blocks the encoder needs to be prepared to create
+ // at maximum and --block-list will simultaneously cause new
+ // Blocks to be started at specified intervals. To keep things
+ // logical, the same should be done in single-threaded mode.
+ if (opt_block_list != NULL)
+ block_remaining = opt_block_list[list_pos];
+ }
strm.next_out = out_buf.u8;
strm.avail_out = IO_BUFFER_SIZE;
@@ -527,7 +597,17 @@
if (ret == LZMA_STREAM_END && action == LZMA_FULL_FLUSH) {
// Start a new Block.
action = LZMA_RUN;
- block_remaining = opt_block_size;
+
+ if (opt_block_list == NULL) {
+ block_remaining = opt_block_size;
+ } else {
+ // FIXME: Make it work together with
+ // --block-size.
+ if (opt_block_list[list_pos + 1] != 0)
+ ++list_pos;
+
+ block_remaining = opt_block_list[list_pos];
+ }
} else if (ret != LZMA_OK) {
// Determine if the return value indicates that we
diff --git a/src/xz/coder.h b/src/xz/coder.h
index 578d2d7..583da8f 100644
--- a/src/xz/coder.h
+++ b/src/xz/coder.h
@@ -48,6 +48,10 @@
/// of input. This has an effect only when compressing to the .xz format.
extern uint64_t opt_block_size;
+/// This is non-NULL if --block-list was used. This contains the Block sizes
+/// as an array that is terminated with 0.
+extern uint64_t *opt_block_list;
+
/// Set the integrity check type used when compressing
extern void coder_set_check(lzma_check check);
diff --git a/src/xz/hardware.c b/src/xz/hardware.c
index a4733c2..925926c 100644
--- a/src/xz/hardware.c
+++ b/src/xz/hardware.c
@@ -14,9 +14,9 @@
#include "tuklib_cpucores.h"
-/// Maximum number of free *coder* threads. This can be set with
+/// Maximum number of worker threads. This can be set with
/// the --threads=NUM command line option.
-static uint32_t threadlimit;
+static uint32_t threads_max = 1;
/// Memory usage limit for compression
static uint64_t memlimit_compress;
@@ -29,15 +29,16 @@
extern void
-hardware_threadlimit_set(uint32_t new_threadlimit)
+hardware_threads_set(uint32_t n)
{
- if (new_threadlimit == 0) {
- // The default is the number of available CPU cores.
- threadlimit = tuklib_cpucores();
- if (threadlimit == 0)
- threadlimit = 1;
+ if (n == 0) {
+ // Automatic number of threads was requested.
+ // Use the number of available CPU cores.
+ threads_max = tuklib_cpucores();
+ if (threads_max == 0)
+ threads_max = 1;
} else {
- threadlimit = new_threadlimit;
+ threads_max = n;
}
return;
@@ -45,9 +46,9 @@
extern uint32_t
-hardware_threadlimit_get(void)
+hardware_threads_get(void)
{
- return threadlimit;
+ return threads_max;
}
@@ -139,6 +140,5 @@
// Set the defaults.
hardware_memlimit_set(0, true, true, false);
- hardware_threadlimit_set(0);
return;
}
diff --git a/src/xz/hardware.h b/src/xz/hardware.h
index ad526f2..4fae618 100644
--- a/src/xz/hardware.h
+++ b/src/xz/hardware.h
@@ -15,12 +15,11 @@
extern void hardware_init(void);
-/// Set custom value for maximum number of coder threads.
-extern void hardware_threadlimit_set(uint32_t threadlimit);
+/// Set the maximum number of worker threads.
+extern void hardware_threads_set(uint32_t threadlimit);
-/// Get the maximum number of coder threads. Some additional helper threads
-/// are allowed on top of this).
-extern uint32_t hardware_threadlimit_get(void);
+/// Get the maximum number of worker threads.
+extern uint32_t hardware_threads_get(void);
/// Set the memory usage limit. There are separate limits for compression
diff --git a/src/xz/main.c b/src/xz/main.c
index 4e5b49e..a8f0683 100644
--- a/src/xz/main.c
+++ b/src/xz/main.c
@@ -277,6 +277,7 @@
#ifndef NDEBUG
coder_free();
+ args_free();
#endif
// If we have got a signal, raise it to kill the program instead
diff --git a/src/xz/message.c b/src/xz/message.c
index 2b6ac5f..abbd171 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -1153,10 +1153,16 @@
" does not affect decompressor memory requirements"));
if (long_help) {
+ // FIXME? Mention something about threading?
puts(_(
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
" after every SIZE bytes of input; 0=disabled (default)"));
+ // FIXME
+ puts(_(
+" --block-list=SIZES\n"
+" when compressing to the .xz format, start a new block\n"
+" after the given intervals of uncompressed data"));
puts(_( // xgettext:no-c-format
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
diff --git a/src/xz/private.h b/src/xz/private.h
index 6b01e51..978f81a 100644
--- a/src/xz/private.h
+++ b/src/xz/private.h
@@ -12,6 +12,8 @@
#include "sysdefs.h"
#include "mythread.h"
+
+#define LZMA_UNSTABLE
#include "lzma.h"
#include <sys/types.h>
diff --git a/src/xz/xz.1 b/src/xz/xz.1
index 0952f2d..9038f69 100644
--- a/src/xz/xz.1
+++ b/src/xz/xz.1
@@ -5,7 +5,7 @@
.\" This file has been put into the public domain.
.\" You can do whatever you want with this file.
.\"
-.TH XZ 1 "2012-07-01" "Tukaani" "XZ Utils"
+.TH XZ 1 "2012-07-04" "Tukaani" "XZ Utils"
.
.SH NAME
xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
@@ -807,7 +807,32 @@
.I size
bytes.
The blocks are compressed independently from each other.
-.\" FIXME: Explain how to his can be used for random access and threading.
+.\" FIXME: Explain how to these can be used for random access and threading.
+.TP
+.BI \-\-block\-list= sizes
+When compressing to the
+.B .xz
+format, start a new block after
+the given intervals of uncompressed data.
+.IP ""
+The uncompressed
+.I sizes
+of the blocks are specified as a comma-separated list.
+Omitting a size (two or more consecutive commas) is a shorthand
+to use the size of the previous block.
+.IP ""
+If the input file is bigger than the sum of
+.IR sizes ,
+the last value in
+.I sizes
+is repeated until the end of the file.
+A special value of
+.B 0
+may be used as the last value to indicate that
+the rest of the file should be encoded as a single block.
+.IP ""
+.B "Currently this option is badly broken if used together with"
+.B "\-\-block\-size or with multithreading."
.TP
.BI \-\-memlimit\-compress= limit
Set a memory usage limit for compression.
@@ -907,24 +932,30 @@
.TP
\fB\-T\fR \fIthreads\fR, \fB\-\-threads=\fIthreads
Specify the number of worker threads to use.
+Setting
+.I threads
+to a special value
+.B 0
+makes
+.B xz
+use as many threads as there are CPU cores on the system.
The actual number of threads can be less than
.I threads
+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 ""
-.B "Multithreaded compression and decompression are not"
-.B "implemented yet, so this option has no effect for now."
+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 overriden with the
+.BI \-\-block\-size= size
+option.
.IP ""
-.B "As of writing (2010-09-27), it hasn't been decided"
-.B "if threads will be used by default on multicore systems"
-.B "once support for threading has been implemented."
-.B "Comments are welcome."
-The complicating factor is that using many threads
-will increase the memory usage dramatically.
-Note that if multithreading will be the default,
-it will probably be done so that single-threaded and
-multithreaded modes produce the same output,
-so compression ratio won't be significantly affected
-if threading will be enabled by default.
+.B "It is possible that the details of this option change before"
+.B "the next stable XZ Utils release."
+.B "This may include the meaning of the special value 0."
+.\" FIXME
.
.SS "Custom compressor filter chains"
A custom filter chain allows specifying
diff --git a/tests/test_block.c b/tests/test_block.c
deleted file mode 100644
index 0352dce..0000000
--- a/tests/test_block.c
+++ /dev/null
@@ -1,52 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file test_block.c
-/// \brief Tests Block coders
-//
-// Author: Lasse Collin
-//
-// This file has been put into the public domain.
-// You can do whatever you want with this file.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "tests.h"
-
-
-static uint8_t text[] = "Hello world!";
-static uint8_t buffer[4096];
-static lzma_options_block block_options;
-static lzma_stream strm = LZMA_STREAM_INIT;
-
-
-static void
-test1(void)
-{
-
-}
-
-
-int
-main()
-{
- lzma_init();
-
- block_options = (lzma_options_block){
- .check_type = LZMA_CHECK_NONE,
- .has_eopm = true,
- .has_uncompressed_size_in_footer = false,
- .has_backward_size = false,
- .handle_padding = false,
- .total_size = LZMA_VLI_UNKNOWN,
- .compressed_size = LZMA_VLI_UNKNOWN,
- .uncompressed_size = LZMA_VLI_UNKNOWN,
- .header_size = 5,
- };
- block_options.filters[0].id = LZMA_VLI_UNKNOWN;
- block_options.filters[0].options = NULL;
-
-
- lzma_end(&strm);
-
- return 0;
-}