Vendor import of xz (stripped)

Git revision:	d52b411716a614c202e89ba732492efb9916cd3f

Approved by:	delphij (mentor)
This commit is contained in:
mm 2010-10-11 12:43:51 +00:00
parent 1008b7c674
commit 2801acca20
70 changed files with 6554 additions and 3841 deletions

814
ChangeLog
View File

@ -1,3 +1,817 @@
commit d52b411716a614c202e89ba732492efb9916cd3f
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Oct 10 17:58:58 2010 +0300
xz: Use "%"PRIu32 instead of "%d" in a format string.
commit ae74d1bdeb075c3beefe76e1136c5741804e7e91
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Oct 10 17:43:26 2010 +0300
test_files.sh: Fix the first line.
For some reason this prevented running the test only
on OS/2 and even on that it broke only recently.
Thanks to Elbert Pol.
commit d492b80ddd6f9a13419de6d102df7374d8f448e8
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Oct 10 16:49:01 2010 +0300
lzmainfo: Use "%"PRIu32 instead of "%u" for uint32_t.
commit 825e859a9054bd91202e5723c41a17e72f63040a
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Oct 10 16:47:01 2010 +0300
lzmainfo: Use fileno(stdin) instead of STDIN_FILENO.
commit acbc4cdecbeec2a4dfaac04f185ece49b2ff17c8
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 23:20:51 2010 +0300
lzmainfo: Use setmode() on DOS-like systems.
commit ef364d3abc5647111c5424ea0d83a567e184a23b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 21:51:03 2010 +0300
OS/2 and DOS: Be less verbose on signals.
Calling raise() to kill xz when user has pressed C-c
is a bit verbose on OS/2 and DOS/DJGPP. Instead of
calling raise(), set only the exit status to 1.
commit 5629c4be07b6c67e79842b2569da1cedc9c0d69a
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 19:28:49 2010 +0300
DOS: Update the Makefile, config.h and README.
This is now simpler and builds only xz.exe.
commit f25a77e6b9bc48a243ddfbbd755b7960eec7e0ac
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 18:57:55 2010 +0300
Windows: Put some license info into README-Windows.txt.
commit e75100f549f85d231df25c07aa94d63e78e2d668
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 18:57:04 2010 +0300
Windows: Fix a diagnostics bug in build.bash.
commit efeb998a2b1025df1c1d202cc7d21d866cd1c336
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 13:02:15 2010 +0300
lzmainfo: Add Windows resource file.
commit 389d418445f1623593dfdbba55d52fbb6d1205f5
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 12:57:25 2010 +0300
Add missing public domain notice to lzmadec_w32res.rc.
commit 6389c773a4912dd9f111256d74ba1605230a7957
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 12:52:12 2010 +0300
Windows: Update common_w32res.rc.
commit 71275457ca24c9b01721f5cfc3638cf094daf454
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 12:27:08 2010 +0300
Windows: Make build.bash prefer MinGW-w32 over MinGW.
This is simply for licensing reasons. The 64-bit version
will be built with MinGW-w64 anyway (at least for now),
so using it also for 32-bit build allows using the same
copyright notice about the MinGW-w64/w32 runtime.
Note that using MinGW would require a copyright notice too,
because its runtime is not in the public domain either even
though MinGW's home page claims that it is public domain.
See <http://marc.info/?l=mingw-users&m=126489506214078>.
commit 3ac35719d8433af937af6491383d4a50e343099b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 9 11:33:21 2010 +0300
Windows: Copy COPYING-Windows.txt (if it exists) to the package.
Also, put README-Windows.txt to the doc directory like
the other documentation files.
commit 7b5db576fd7a4a67813b8437a9ccd4dbc94bbaae
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Oct 8 21:42:37 2010 +0300
Windows: Fix build.bash again.
630a8beda34af0ac153c8051b1bf01230558e422 wasn't good.
commit d3cd7abe85ec7c2f46cf198b15c00d5d119df3dd
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Oct 8 16:53:20 2010 +0300
Use LZMA_VERSION_STRING instead of PACKAGE_VERSION.
Those are the same thing, and the former makes it a bit
easier to build the code with other build systems, because
one doesn't need to update the version number into custom
config.h.
This change affects only lzmainfo. Other tools were already
using LZMA_VERSION_STRING.
commit 084c60d318f2dbaef4078d9b100b4a373d0c3a7f
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Oct 8 15:59:25 2010 +0300
configure.ac: Remove two unused defines.
commit 11f51b6714357cb67ec7e56ed9575c199b5581fe
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Oct 8 15:32:29 2010 +0300
Make tests accommodate missing xz or xzdec.
commit b1c7368f95e93ccdefdd0748e04398c26766f47f
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Oct 8 15:25:45 2010 +0300
Build: Add options to disable individual command line tools.
commit 630a8beda34af0ac153c8051b1bf01230558e422
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu Oct 7 00:44:53 2010 +0300
Windows: Make build.bash work without --enable-dynamic=no.
commit f9907503f882a745dce9d84c2968f6c175ba966a
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Oct 5 14:13:16 2010 +0300
Build: Remove the static/dynamic tricks.
Most distros want xz linked against shared liblzma, so
it doesn't help much to require --enable-dynamic for that.
Those who want to avoid PIC on x86-32 to get better
performance, can still do it e.g. by using --disable-shared
to compile xz and then another pass to compile shared liblzma.
Part of these static/dynamic tricks were needed for Windows
in the past. Nowadays we rely on GCC and binutils to do the
right thing with auto-import. If the Autotooled build system
needs to support some other toolchain on Windows in the future,
this may need some rethinking.
commit fda4724d8114fccfa31c1839c15479f350c2fb4c
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Oct 5 12:18:58 2010 +0300
configure.ac: Silence a warning from Autoconf 2.68.
commit 80b5675fa62c87426fe86f8fcd20feeabc4361b9
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon Oct 4 19:43:01 2010 +0300
A few more languages files to the xz man page.
Thanks to Jonathan Nieder.
commit f9722dbeca4dc4c43cfd15d122dafaac50b0a0bb
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 2 12:07:33 2010 +0300
Update the FAQ.
commit 61ae593661e8dc402394e84d567ca2044a51572b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Oct 2 11:38:20 2010 +0300
liblzma: Small fixes to comments in the API headers.
commit 9166682dc601fd42c1b9510572e3f917d18de504
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 28 11:40:12 2010 +0300
Create the PDF versions of the man pages better.
commit 17d3c61edd35de8fa884944fc70d1db86daa5dd8
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 28 10:59:53 2010 +0300
Move version.sh to build-aux.
commit 84af9d8770451339a692e9b70f96cf56156a6069
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 28 10:53:02 2010 +0300
Update .gitignore.
commit 31575a449ac64c523da3bab8d0c0b522cdc7c780
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 28 01:17:14 2010 +0300
Fix accomodate -> accommodate on the xz man page.
commit cec0ddc8ec4ce81685a51998b978e22167e461f9
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon Sep 27 23:29:34 2010 +0300
Major man page updates.
Lots of content was updated on the xz man page.
Technical improvements:
- Start a new sentence on a new line.
- Use fairly short lines.
- Use constant-width font for examples (where supported).
- Some minor cleanups.
Thanks to Jonathan Nieder for some language fixes.
commit 075257ab0416a0603be930082e31a5703e4ba345
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Sep 26 18:10:31 2010 +0300
Fix the preset -3e.
depth=0 was missing.
commit 2577da9ebdba13fbe99ae5ee8bde35f7ed60f6d1
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu Sep 23 14:03:10 2010 +0300
Add translations.bash and translation notes to README.
translations.bash prints some messages from xz, which
hopefully makes it a bit easier to test translations.
commit a3c5997c57e5b1a20aae6d1071b584b4f17d0b23
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 17 22:14:30 2010 +0300
xz: Update the Czech translation.
Thanks to Marek Černocký.
commit a1766af582dc23fddd9da1eeb4b9d61e3eb4c2e6
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu Sep 16 23:40:41 2010 +0300
xz: Add Italian translation.
Thanks to Milo Casagrande and Lorenzo De Liso.
commit 21088018554e2b0e02914205377ceb6e34a090bd
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Sep 15 00:34:13 2010 +0300
xz: Edit a translators comment.
commit be16e28ece1b492b8f93382b7fa1cc4da23c6ff6
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 14 22:47:14 2010 +0300
xz: Add German translation.
Thanks to Andre Noll.
commit e23ea74f3240e6b69683f9e69d1716e0f9e9092b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 10 14:30:25 2010 +0300
Updated README.
commit 8dad2fd69336985adb9f774fa96dc9c0efcb5a71
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 10 14:30:07 2010 +0300
Updated INSTALL.
commit 0b5f07fe3728c27cce416ddc40f7e4803ae96ac2
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 10 14:26:20 2010 +0300
Updated the git repository address in ChangeLog.
commit a8760203f93a69bc39fd14520a6e9e7b7d70be06
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 10 14:09:33 2010 +0300
xz: Add a comment to translators about "literal context bits".
commit bb0b1004f83cdc4d309e1471c2ecaf9f95ce60c5
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 10 10:30:33 2010 +0300
xz: Multiple fixes.
The code assumed that printing numbers with thousand separators
and decimal points would always produce only US-ASCII characters.
This was used for buffer sizes (with snprintf(), no overflows)
and aligning columns of the progress indicator and --list. That
assumption was wrong (e.g. LC_ALL=fi_FI.UTF-8 with glibc), so
multibyte character support was added in this commit. The old
way is used if the operating system doesn't have enough multibyte
support (e.g. lacks wcwidth()).
The sizes of buffers were increased to accomodate multibyte
characters. I don't know how big they should be exactly, but
they aren't used for anything critical, so it's not too bad.
If they still aren't big enough, I hopefully get a bug report.
snprintf() takes care of avoiding buffer overflows.
Some static buffers were replaced with buffers allocated on
stack. double_to_str() was removed. uint64_to_str() and
uint64_to_nicestr() now share the static buffer and test
for thousand separator support.
Integrity check names "None" and "Unknown-N" (2 <= N <= 15)
were marked to be translated. I had forgot these, plus they
wouldn't have worked correctly anyway before this commit,
because printing tables with multibyte strings didn't work.
Thanks to Marek Černocký for reporting the bug about
misaligned table columns in --list output.
commit 639f8e2af33cf8a184d59ba56b6df7c098679d61
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Sep 8 08:49:22 2010 +0300
Update the Czech translation.
Thanks to Marek Černocký.
commit 41bc9956ebfd7c86777d33676acf34c45e7ca7c7
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 7 12:31:40 2010 +0300
xz: Add a note to translators.
commit 77a7746616e555fc08028e883a56d06bf0088b81
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Sep 7 10:42:13 2010 +0300
Fix use of N_() and ngettext().
I had somehow thought that N_() is usually used
as shorthand for ngettext().
This also fixes a missing \n from a call to ngettext().
commit e6ad39335842343e622ab51207d1d3cb9caad801
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon Sep 6 19:43:12 2010 +0300
Add missing files to POTFILES.in.
commit 58f55131820d2e08a1a6beb9ec0ee2378044eb30
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon Sep 6 10:16:24 2010 +0300
xz: Improve a comment.
commit bcb1b898341f7073f51660d7052d7ed6c5461a66
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Sep 5 21:34:29 2010 +0300
xz: Update the comment about NetBSD in file_io.c.
Thanks to Joerg Sonnenberger.
commit da014d55972f5addbf6b4360d3d8ed2ef4282170
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Sep 5 21:11:33 2010 +0300
xz: Use an array instead of pointer for stdin_filename.
Thanks Joerg Sonnenberger.
commit 8c7d3d1a0781c296c6b6e2465becaffd2132f7ee
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun Sep 5 12:16:17 2010 +0300
xz: Hopefully ease translating the messages in list.c.
commit ef840950ad99cf2955c754875af0e01acf125079
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Sep 4 23:14:44 2010 +0300
xz: Fix grammar.
commit c46afd6edc04ea140db6c59e8486f5707c810c13
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Sep 4 23:12:20 2010 +0300
xz: Use lzma_lzma_preset() to initialize the options structure.
commit 8fd3ac046d0b1416a2094fecc456d9e0f4d5d065
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Sep 4 22:16:28 2010 +0300
Don't set lc=4 with --extreme.
This should reduce the cases where --extreme makes
compression worse. On the other hand, some other
files may now benefit slightly less from --extreme.
commit 474bac0c33e94aeaca8ada17ab19972b1424bc2b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Sep 4 22:10:32 2010 +0300
xz: Minor improvements to --help and --long-help.
commit 373ee26f955617295c5c537b04a153a1969140d2
Author: Jonathan Nieder <jrnieder@gmail.com>
Date: Fri Sep 3 16:49:15 2010 -0500
Adjust memory limits in test_compress.sh
Testing compression at level -4 now requires 48 MiB of free store at
compression time and 5 MiB at decompression time.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
commit 2fce9312f36727ea82f3430cc5d3a7d243c5f087
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 3 15:54:40 2010 +0300
xz: Make -vv show also decompressor memory usage.
commit b4b1cbcb53624ab832f8b3189c74450dc7ea29b6
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 3 15:13:12 2010 +0300
Tweak the compression presets -0 .. -5.
"Extreme" mode might need some further tweaking still.
Docs were not updated yet.
commit 77fe5954cd3d10fb1837372684cbc133b56b6a87
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 3 12:28:41 2010 +0300
liblzma: Adjust default depth calculation for HC3 and HC4.
It was 8 + nice_len / 4, now it is 4 + nice_len / 4.
This allows faster settings at lower nice_len values,
even though it seems that I won't use automatic depth
calcuation with HC3 and HC4 in the presets.
commit fce69059cf901ce8075a78c7607d591f144a3b5a
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Sep 3 11:11:25 2010 +0300
xz: Make --help two lines shorter.
At least for now, the --help option doesn't list any
options that take arguments, so "Mandatory arguments to..."
can be omitted.
commit a848e47ced6e5e2a564b5c454b2f5a19c2f40298
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu Sep 2 19:22:35 2010 +0300
xz: Make setting a preset override a custom filter chain.
This is more logical behavior than ignoring preset level
options once a custom filter chain has been specified.
commit b3ff7ba044eaeab3e424d7b51fe914daf681b1a3
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu Sep 2 19:09:57 2010 +0300
xz: Always warn if adjusting dictionary size due to memlimit.
commit d5653ba8a1ea9c00de4fddc617aba3c51e18139d
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Aug 10 11:04:30 2010 +0300
Fix test_compress.sh.
It broke when --memory option was removed from xzdec.
Thanks to Jonathan Nieder.
commit 792331bdee706aa852a78b171040ebf814c6f3ae
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sat Aug 7 20:45:18 2010 +0300
Disable the memory usage limiter by default.
For several people, the limiter causes bigger problems that
it solves, so it is better to have it disabled by default.
Those who want to have a limiter by default need to enable
it via the environment variable XZ_DEFAULTS.
Support for environment variable XZ_DEFAULTS was added. It is
parsed before XZ_OPT and technically identical with it. The
intended uses differ quite a bit though; see the man page.
The memory usage limit can now be set separately for
compression and decompression using --memlimit-compress and
--memlimit-decompress. To set both at once, -M or --memlimit
can be used. --memory was retained as a legacy alias for
--memlimit for backwards compatibility.
The semantics of --info-memory were changed in backwards
incompatible way. Compatibility wasn't meaningful due to
changes in the memory usage limiter functionality.
The memory usage limiter info is no longer shown at the
bottom of xz --long -help.
The memory usage limiter support for removed completely from xzdec.
xz's man page was updated to match the above changes. Various
unrelated fixes were also made to the man page.
commit 4a45dd4c39f75d25c7a37b6400cb24d4010ca801
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Aug 6 20:22:16 2010 +0300
Add missing const to a global constant in xz.
commit 01aa4869cb220b7fdad6d1acbabb2233045daa8f
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Jul 28 11:44:55 2010 +0300
Language fixes for man pages.
Thanks to A. Costa and Jonathan Nieder.
commit ce1f0deafe8504e1492bf1b1efb3e3ec950b1a2b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jul 27 20:47:12 2010 +0300
Windows: Add a note about building a Git repository snapshot
commit 507a4a4dea1e5462f12f7ed4b076c34e02054a38
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jul 27 20:45:03 2010 +0300
Windows: build.sh is a bash script so name it correctly.
commit b1cbfd40f049a646a639eb78a3e41e9e3ef73339
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jul 27 20:27:32 2010 +0300
Windows: Don't strip liblzma.a too much.
commit a540198ffb25fad36380c5e92ac20c2d28eec46a
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jul 13 20:07:26 2010 +0300
Updated THANKS.
commit bab0f01ed931f606b4675aa9f9331a17cec09bad
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jul 13 19:55:50 2010 +0300
Add two simple example programs.
Hopefully these help a bit when learning the basics
of liblzma API. I plan to write detailed examples about
both basic and advanced features with lots of comments,
but these two examples are good have right now.
The examples were written by Daniel Mealha Cabrita. Thanks.
commit c15c42abb3c8c6e77c778ef06c97a4a10b8b5d00
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jun 15 14:06:29 2010 +0300
Add --no-adjust.
commit 2130926dd1c839280358172dfadd8d3054bde2b4
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Jun 11 21:51:32 2010 +0300
Updated THANKS.
commit bc612d0e0c9e4504c59d49168e87a7ae3e458443
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Jun 11 21:48:32 2010 +0300
Clarify the description of the default memlimit in the man page.
Thanks to Denis Excoffier.
commit e1b6935d60a00405e6b5b455a3426d2248cc926c
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Jun 11 21:43:28 2010 +0300
Fix string to uint64_t conversion.
Thanks to Denis Excoffier for the bug report.
commit 3e49c8acb0f5312948eddb2342dbb5802d4571d0
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri Jun 11 10:40:28 2010 +0300
Put the git commit to the filename in mydist rule.
commit d8b41eedce486d400f701b757b7b5e4e32276618
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Jun 2 23:13:55 2010 +0300
Fix compiling with -Werror.
commit b5fbab6123a39c9a55cd5d7af410e9aae067d5f8
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Jun 2 23:09:22 2010 +0300
Silence a bogus Valgrind warning.
When using -O2 with GCC, it liked to swap two comparisons
in one "if" statement. It's otherwise fine except that
the latter part, which is seemingly never executed, got
executed (nothing wrong with that) and then triggered
warning in Valgrind about conditional jump depending on
uninitialized variable. A few people find this annoying
so do things a bit differently to avoid the warning.
commit 29a7b250e685852f2f97615493ec49acaf528623
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Jun 2 21:32:12 2010 +0300
Fix a Windows-specific FIXME in signal handling code.
commit e89d987056cee7d4e279be3ef3a6cc690bfc0e6d
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed Jun 2 17:46:58 2010 +0300
Adjust SA_RESTART workaround.
I want to get a bug report if something else than
DJGPP lacks SA_RESTART.
commit e243145c84ab5c3be8259fd486ead0de5235b3f0
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jun 1 16:02:30 2010 +0300
xz man page updates.
- Concatenating .xz files and padding
- List mode
- Robot mode
- A few examples (but many more are needed)
commit ce6dc3c0a891f23a862f80ec08d3b6f0beb2a562
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jun 1 15:51:44 2010 +0300
Major update to xz --list.
commit 905e54804a899e4ad526d38fdba7e803ab9b71bd
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jun 1 14:13:03 2010 +0300
Rename message_filters_get() to message_filters_to_str().
commit 4b346ae8af20045027ae5efb068c6d69da3324d2
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Tue Jun 1 14:09:12 2010 +0300
Fix a comment.
commit 07dc34f6da45c9ab757dad7fd5eef522ad27d296
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu May 27 16:17:42 2010 +0300
Fix lzma_block_compressed_size().
commit 44d70cb154225e47eebf15a3cfbdf3794cbb4593
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu May 27 14:32:51 2010 +0300
Take Cygwin into account in some #if lines.
This change is no-op, but good to have just in case
for the future.
commit a334348dc02803241cf4e0a539eecdc0e7ad2cc7
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu May 27 13:42:44 2010 +0300
Remove references to the Subblock filter in xz and tests.
Thanks to Jonathan Nieder.
commit 70e5e2f6a7084e6af909deee88ceac2f6efa7893
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Thu May 27 13:35:36 2010 +0300
Remove unused chunk_size.c.
Thanks to Jonathan Nieder for the reminder.
commit 01a414eaf4be6352c06b48001b041b47e8202faa
Author: Jonathan Nieder <jrnieder@gmail.com>
Date: Thu May 27 02:31:33 2010 -0500
Use my_min() instead of MIN() in src/xz/list.c
This should have been done in
920a69a8d8e4203c5edddd829d932130eac188ea.
commit 920a69a8d8e4203c5edddd829d932130eac188ea
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed May 26 10:36:46 2010 +0300
Rename MIN() and MAX() to my_min() and my_max().
This should avoid some minor portability issues.
commit 019ae27c24d0c694545a6a46f8b9fb552198b015
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed May 26 10:30:20 2010 +0300
Fix compilation of debug/known_sizes.c.
commit 98a4856a6ea84f79c790057a6eb89a25bc45b074
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed May 26 10:28:54 2010 +0300
Remove references to Subblock filter in debug/sync_flush.c.
commit 703d2c33c095c41ae0693ee8c27c45e3847e4535
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed May 26 10:16:57 2010 +0300
Better #error message.
commit d8a55c48b39703dd83f11089ad01e1ff2ac102e0
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Wed May 26 09:55:47 2010 +0300
Remove the Subblock filter code for now.
The spec isn't finished and the code didn't compile anymore.
It won't be included in XZ Utils 5.0.0. It's easy to get it
back once the spec is done.
commit b6377fc990f9b8651149cae0fecb8b9c5904e26d
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Sun May 16 18:42:22 2010 +0300
Split message_filters().
message_filters_to_str() converts the filter chain to
a string. message_filters_show() replaces the original
message_filters().
uint32_to_optstr() was also added to show the dictionary
size in nicer format when possible.
commit d9986db782d6cf0f314342127280519339378fa0
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Fri May 14 23:17:20 2010 +0300
Omit lzma_restrict from the API headers.
It isn't really useful so omitting it makes things
shorter and slightly more readable.
commit 0d3489efca0a723dca0394809fa3e6170843af4b
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon May 10 19:57:24 2010 +0300
Updated INSTALL.
commit 3fb3d594a2b53886adee161b6261e92277f05f7c
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon May 10 19:54:52 2010 +0300
Updated THANKS.
commit 6548e304657e77d3a972053db3c41c5daf591113
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon May 10 19:54:15 2010 +0300
Updates to tuklib_physmem and tuklib_cpucores.
Don't use #error to generate compile error, because some
compilers actually don't take it as an error. This fixes
tuklib_physmem on IRIX.
Fix incorrect error check for sysconf() return values.
Add AIX, HP-UX, and Tru64 specific code to detect the
amount RAM.
Add HP-UX specific code to detect the number of CPU cores.
Thanks a lot to Peter O'Gorman for initial patches,
testing, and debugging these fixes.
commit a290cfee3e23f046889c022aa96b4eca2016fdda
Author: Lasse Collin <lasse.collin@tukaani.org>
Date: Mon Apr 12 21:55:56 2010 +0300

37
FREEBSD-Xlist Normal file
View File

@ -0,0 +1,37 @@
$FreeBSD$
*/*/*/Makefile.*
*/*/Makefile.*
*/.gitignore
*/Makefile.*
.git
.gitignore
ABOUT-NLS
COPYING.GPLv2
COPYING.GPLv3
COPYING.LGPLv2.1
Doxyfile.in
INSTALL
INSTALL.generic
Makefile
Makefile.*
NEWS
PACKAGERS
aclocal.m4
autogen.sh
build-aux/
config.h.in
configure
configure.ac
debug/
doc/
dos/
extra/
lib/
m4/
makefile.am
src/*/*.rc
src/liblzma/liblzma.pc.in
src/scripts/
tests/
version.sh
windows/

28
FREEBSD-upgrade Normal file
View File

@ -0,0 +1,28 @@
$FreeBSD$
xz
The source code is pulled with git:
git clone git://ctrl.tukaani.org/xz.git xz
ChangeLog is generated with:
git log > ChangeLog
For the import files and directories were pruned by:
sh -c 'for F in `cat FREEBSD-Xlist | grep -v FreeBSD`; do rm -rf ./$F ; done'
You may check if there are any new files that we don't need.
The instructions for importing new release and merging to HEAD can be found
at FreeBSD wiki:
http://wiki.freebsd.org/SubversionPrimer/VendorImports
To make local changes to xz, simply patch and commit to the trunk
branch (aka HEAD). Never make local changes on the vendor branch.
mm@FreeBSD.org
10-May-2010

98
README
View File

@ -9,8 +9,9 @@ XZ Utils
1.3. Documentation for liblzma
2. Version numbering
3. Reporting bugs
4. Other implementations of the .xz format
5. Contact information
4. Translating the xz tool
5. Other implementations of the .xz format
6. Contact information
0. Overview
@ -187,7 +188,94 @@ XZ Utils
system.
4. Other implementations of the .xz format
4. Translating the xz tool
--------------------------
The messages from the xz tool have been translated into a few
languages. Before starting to translate into a new language, ask
the author that someone else hasn't already started working on it.
Test your translation. Testing includes comparing the translated
output to the original English version by running the same commands
in both your target locale and with LC_ALL=C. Ask someone to
proof-read and test the translation.
Testing can be done e.g. by installing xz into a temporary directory:
./configure --disable-shared --prefix=/tmp/xz-test
# <Edit the .po file in the po directory.>
make -C po update-po
make install
bash debug/translations.bash | less
bash debug/translations.bash | less -S # For --list outputs
Repeat the above as needed (no need to re-run configure though).
Note especially the following:
- The output of --help and --long-help must look nice on
a 80-column terminal. It's OK to add extra lines if needed.
- In contrast, don't add extra lines to error messages and such.
They are often preceded with e.g. a filename on the same line,
so you have no way to predict where to put a \n. Let the terminal
do the wrapping even if it looks ugly. Adding new lines will be
even uglier in the generic case even if it looks nice in a few
limited examples.
- Be careful with column alignment in tables and table-like output
(--list, --list --verbose --verbose, --info-memory, --help, and
--long-help):
* All descriptions of options in --help should start in the
same column (but it doesn't need to be the same column as
in the English messages; just be consistent if you change it).
Check that both --help and --long-help look OK, since they
share several strings.
* --list --verbose and --info-memory print lines that have
the format "Description: %s". If you need a longer
description, you can put extra space between the colon
and %s. Then you may need to add extra space to other
strings too so that the result as a whole looks good (all
values start at the same column).
* The columns of the actual tables in --list --verbose --verbose
should be aligned properly. Abbreviate if necessary. It might
be good to keep at least 2 or 3 spaces between column headings
and avoid spaces in the headings so that the columns stand out
better, but this is a matter of opinion. Do what you think
looks best.
- Be careful to put a period at the end of a sentence when the
original version has it, and don't put it when the original
doesn't have it. Similarly, be careful with \n characters
at the beginning and end of the strings.
- Read the TRANSLATORS comments that have been extracted from the
source code and included in xz.pot. If they suggest testing the
translation with some type of command, do it. If testing needs
input files, use e.g. tests/files/good-*.xz.
- When updating the translation, read the fuzzy (modified) strings
carefully, and don't mark them as updated before you actually
have updated them. Reading through the unchanged messages can be
good too; sometimes you may find a better wording for them.
- If you find language problems in the original English strings,
feel free to suggest improvements. Ask if something is unclear.
- The translated messages should be understandable (sometimes this
may be a problem with the original English messages too). Don't
make a direct word-by-word translation from English especially if
the result doesn't sound good in your language.
In short, take your time and pay attention to the details. Making
a good translation is not a quick and trivial thing to do. The
translated xz should look as polished as the English version.
5. Other implementations of the .xz format
------------------------------------------
7-Zip and the p7zip port of 7-Zip support the .xz format starting
@ -202,13 +290,11 @@ XZ Utils
http://tukaani.org/xz/embedded.html
5. Contact information
6. Contact information
----------------------
If you have questions, bug reports, patches etc. related to XZ Utils,
contact Lasse Collin <lasse.collin@tukaani.org> (in Finnish or English).
tukaani.org uses greylisting to reduce spam, thus when you send your
first email, it may get delayed by a few hours. In addition to that,
I'm sometimes slow at replying. If you haven't got a reply within two
weeks, assume that your email has got lost and resend it or use IRC.

6
THANKS
View File

@ -12,12 +12,15 @@ has been important. :-) In alphabetical order:
- Emmanuel Blot
- Trent W. Buck
- David Burklund
- Daniel Mealha Cabrita
- Milo Casagrande
- Marek Černocký
- Andrew Dudman
- Markus Duft
- İsmail Dönmez
- Robert Elz
- Gilles Espinasse
- Denis Excoffier
- Mike Frysinger
- Joachim Henke
- Peter Ivanov
@ -30,11 +33,14 @@ has been important. :-) In alphabetical order:
- Peter Lawler
- Hin-Tak Leung
- Andraž 'ruskie' Levstik
- Lorenzo De Liso
- Jim Meyering
- Rafał Mużyło
- Adrien Nader
- Hongbo Ni
- Jonathan Nieder
- Andre Noll
- Peter O'Gorman
- Igor Pavlov
- Elbert Pol
- Mikko Pouru

View File

@ -1 +1,3 @@
cs
de
it

View File

@ -3,8 +3,11 @@ src/xz/args.c
src/xz/coder.c
src/xz/file_io.c
src/xz/hardware.c
src/xz/list.c
src/xz/main.c
src/xz/message.c
src/xz/options.c
src/xz/signals.c
src/xz/suffix.c
src/xz/util.c
src/common/tuklib_exit.c

725
po/cs.po

File diff suppressed because it is too large Load Diff

903
po/de.po Normal file
View File

@ -0,0 +1,903 @@
# XZ Utils German translation
# This file is put in the public domain.
# Andre Noll <maan@systemlinux.org>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: XZ Utils 4.999.9beta\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
"POT-Creation-Date: 2010-09-11 17:07+0200\n"
"PO-Revision-Date: 2010-09-07 20:27+0200\n"
"Last-Translator: <maan@systemlinux.org>\n"
"Language-Team: German\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:333
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Unbekanntes file format"
#: src/xz/args.c:356 src/xz/args.c:364
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Integritäts-Check Typ nicht unterstützt"
#: src/xz/args.c:382
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."
#: src/xz/args.c:445
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Die Umgebungsvariable %s enthält zu viele Argumente"
#: src/xz/coder.c:95
msgid "Maximum number of filters is four"
msgstr "Maximal vier Filter möglich"
#: src/xz/coder.c:108
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."
#: src/xz/coder.c:129
msgid "Using a preset in raw mode is discouraged."
msgstr "Verwendung der Voreinstellung im raw Modus wird nicht empfohlen."
#: src/xz/coder.c:131
msgid "The exact options of the presets may vary between software versions."
msgstr ""
"Die genauen Optionen der Voreinstellung können zwischen Software Versionen "
"variieren."
#: src/xz/coder.c:157
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Das .lzma Format unterstützt nur den LZMA1 Filter"
#: src/xz/coder.c:165
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 kann nicht mit dem .xz Format verwendet werden"
#: src/xz/coder.c:182
msgid "Unsupported filter chain or filter options"
msgstr "Optionen nicht unterstützt"
#: src/xz/coder.c:190
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "Dekompression wird %s MiB Speicher brauchen."
#: src/xz/coder.c:247
#, 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
#. if the source file still exists, and if it does, does its
#. device and inode numbers match what xz saw when it opened
#. the source file. If these checks fail, this message is
#. shown, %s being the filename, and the file is not deleted.
#. The check for device and inode numbers is there, because
#. it is possible that the user has put a new file in place
#. of the original file, and in that case it obviously
#. shouldn't be removed.
#: src/xz/file_io.c:137
#, 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"
#: src/xz/file_io.c:144 src/xz/file_io.c:590
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s: Kann nicht löschen: %s"
#: src/xz/file_io.c:169
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s: Kann Datei Eigentümer nicht setzen: %s"
#: src/xz/file_io.c:175
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s: Kann Datei Gruppe nicht setzen: %s"
#: src/xz/file_io.c:194
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s: Kann Zugriffsrechte nicht setzen: %s"
#: src/xz/file_io.c:337 src/xz/file_io.c:420
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s: Überspringe symbolischen Verweis"
#: src/xz/file_io.c:455
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s: Überspringe Verzeichnis"
#: src/xz/file_io.c:462
#, c-format
msgid "%s: Not a regular file, skipping"
msgstr "%s: Keine reguläre Datei, überspringe"
#: src/xz/file_io.c:479
#, c-format
msgid "%s: File has setuid or setgid bit set, skipping"
msgstr "%s: Datei hat das setuid oder setgid Bit gesetzt, überspringe"
#: src/xz/file_io.c:486
#, c-format
msgid "%s: File has sticky bit set, skipping"
msgstr "%s: Datei hat sticky Bit gesetzt, überspringe"
#: src/xz/file_io.c:493
#, c-format
msgid "%s: Input file has more than one hard link, skipping"
msgstr "%s: Eingabedatei hat mehr als einen hard link, überspringe"
#: src/xz/file_io.c:714
#, 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"
#: src/xz/file_io.c:726
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s: Fehler beim Schießen der Datei: %s"
#: src/xz/file_io.c:762 src/xz/file_io.c:946
#, 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"
#: src/xz/file_io.c:821
#, c-format
msgid "%s: Read error: %s"
msgstr "%s: Lesefehler: %s"
#: src/xz/file_io.c:844
#, c-format
msgid "%s: Error seeking the file: %s"
msgstr "%s: Fehler beim Lesen der Dateinamen: %s"
#: src/xz/file_io.c:854
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s: Unerwartetes Ende der Datei"
#: src/xz/file_io.c:904
#, c-format
msgid "%s: Write error: %s"
msgstr "%s: Schreibfehler: %s"
#: src/xz/hardware.c:100
msgid "Disabled"
msgstr "Deaktiviert"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
#: src/xz/hardware.c:119
msgid "Total amount of physical memory (RAM): "
msgstr "Gesamtmenge physikalischer Speicher (RAM): "
#: src/xz/hardware.c:121
msgid "Memory usage limit for compression: "
msgstr "Speicher Nutzungslimit für Kompression: "
#: src/xz/hardware.c:123
msgid "Memory usage limit for decompression: "
msgstr "Speicher Nutzungslimit für Dekompression: "
#. 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
msgid "None"
msgstr "Kein"
#. TRANSLATORS: Indicates that integrity check name is not known,
#. but the Check ID is known (here 2). This and other "Unknown-N"
#. 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.
#: src/xz/list.c:69
msgid "Unknown-2"
msgstr "Unbek.2"
#: src/xz/list.c:70
msgid "Unknown-3"
msgstr "Unbek.3"
#: src/xz/list.c:72
msgid "Unknown-5"
msgstr "Unbek.5"
#: src/xz/list.c:73
msgid "Unknown-6"
msgstr "Unbek.6"
#: src/xz/list.c:74
msgid "Unknown-7"
msgstr "Unbek.7"
#: src/xz/list.c:75
msgid "Unknown-8"
msgstr "Unbek.8"
#: src/xz/list.c:76
msgid "Unknown-9"
msgstr "Unbek.9"
#: src/xz/list.c:78
msgid "Unknown-11"
msgstr "Unbek.11"
#: src/xz/list.c:79
msgid "Unknown-12"
msgstr "Unbek.12"
#: src/xz/list.c:80
msgid "Unknown-13"
msgstr "Unbek.13"
#: src/xz/list.c:81
msgid "Unknown-14"
msgstr "Unbek.14"
#: src/xz/list.c:82
msgid "Unknown-15"
msgstr "Unbek.15"
#: src/xz/list.c:126
#, c-format
msgid "%s: File is empty"
msgstr "%s: Datei ist leer"
#: src/xz/list.c:131
#, c-format
msgid "%s: Too small to be a valid .xz file"
msgstr "%s: Zu klein um ein gültiges .xz file zu sein"
#. TRANSLATORS: These are column headings. From Strms (Streams)
#. to Ratio, the columns are right aligned. Check and Filename
#. are left aligned. If you need longer words, it's OK to
#. use two lines here. Test with "xz -l foo.xz".
#: src/xz/list.c:612
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr " Str. Blöcke Kompr. Unkompr. Verh. Check Dateiname"
#: src/xz/list.c:652
#, c-format
msgid " Streams: %s\n"
msgstr " Ströme: %s\n"
#: src/xz/list.c:654
#, c-format
msgid " Blocks: %s\n"
msgstr " Blöcke: %s\n"
#: src/xz/list.c:656
#, c-format
msgid " Compressed size: %s\n"
msgstr " Größe komprimiert: %s\n"
#: src/xz/list.c:659
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Größe unkomprimiert: %s\n"
#: src/xz/list.c:662
#, c-format
msgid " Ratio: %s\n"
msgstr " Verhältnis: %s\n"
#: src/xz/list.c:664
#, c-format
msgid " Check: %s\n"
msgstr " Check: %s\n"
#: src/xz/list.c:665
#, c-format
msgid " Stream padding: %s\n"
msgstr " Strom Auffüllung: %s\n"
#. 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
msgid ""
" Streams:\n"
" 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"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
#: src/xz/list.c:748
#, c-format
msgid ""
" Blocks:\n"
" Stream Block CompOffset UncompOffset TotalSize "
"UncompSize Ratio Check"
msgstr ""
" Blöcke:\n"
" Strom Block KompOffset UnkompOffset TotalGröße "
"UnkompGröße Verh. Check"
#. TRANSLATORS: These are additional column headings
#. for the most verbose listing mode. CheckVal
#. (Check value), Flags, and Filters are left aligned.
#. Header (Block Header Size), CompSize, and MemUsage
#. 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
#, c-format
msgid " CheckVal %*s Header Flags CompSize MemUsage Filters"
msgstr " CheckWert %*s Kopf Schalter KompGröße Speicher Filter"
#: src/xz/list.c:838 src/xz/list.c:1007
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Benötigter Speicher: %s MiB\n"
#: src/xz/list.c:840 src/xz/list.c:1009
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Größe in Köpfen: %s\n"
#: src/xz/list.c:841 src/xz/list.c:1010
msgid "Yes"
msgstr "Ja"
#: src/xz/list.c:841 src/xz/list.c:1010
msgid "No"
msgstr "Nein"
#. 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
#, c-format
msgid "%s file\n"
msgid_plural "%s files\n"
msgstr[0] "%s Datei\n"
msgstr[1] "%s Dateien\n"
#: src/xz/list.c:999
msgid "Totals:"
msgstr "Gesamt:"
#: src/xz/list.c:1000
#, c-format
msgid " Number of files: %s\n"
msgstr " Anzahl Dateien: %s\n"
#: src/xz/list.c:1072
msgid "--list works only on .xz files (--format=xz or --format=auto)"
msgstr ""
"--list funktioniert nur mit .xz Dateien (--format=xz oder --format=auto)"
#: src/xz/list.c:1078
msgid "--list does not support reading from standard input"
msgstr "--list unterstützt kein Lesen der Standardeingabe"
#: src/xz/main.c:89
#, c-format
msgid "%s: Error reading filenames: %s"
msgstr "%s: Fehler beim Lesen der Dateinamen: %s"
#: src/xz/main.c:96
#, c-format
msgid "%s: Unexpected end of input when reading filenames"
msgstr "%s: Unerwartetes Ende beim Lesen der Dateinamen"
#: 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'?"
#: 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"
#: src/xz/message.c:800 src/xz/message.c:844
msgid "Internal error (bug)"
msgstr "Interner Fehler (Bug)"
#: src/xz/message.c:807
msgid "Cannot establish signal handlers"
msgstr "Kann Signal Routine nicht setzen"
#: src/xz/message.c:816
msgid "No integrity check; not verifying file integrity"
msgstr "Kein Integritäts-Check; werde Datei-Integrität nicht überprüfen"
#: src/xz/message.c:819
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"
#: src/xz/message.c:826
msgid "Memory usage limit reached"
msgstr "Speicher-Limit erreicht"
#: src/xz/message.c:829
msgid "File format not recognized"
msgstr "Datei Format nicht erkannt"
#: src/xz/message.c:832
msgid "Unsupported options"
msgstr "Optionen nicht unterstützt"
#: src/xz/message.c:835
msgid "Compressed data is corrupt"
msgstr "Komprimierte Daten sind korrupt"
#: src/xz/message.c:838
msgid "Unexpected end of input"
msgstr "Unerwartetes Eingabe Ende"
#: src/xz/message.c:886
#, c-format
msgid "%s MiB of memory is required. The limit is %s."
msgstr "%s MiB Speicher wird benötigt. Limit ist %s."
#: src/xz/message.c:1053
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s: Filter Kette: %s\n"
#: src/xz/message.c:1063
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Versuchen Sie `%s --help' für mehr Informationen."
#: src/xz/message.c:1089
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
"Compress or decompress FILEs in the .xz format.\n"
"\n"
msgstr ""
"Benutzung: %s [OPTION]... [DATEI]...\n"
"Komprimiert oder dekomprimiert .xz DATEI(EN).\n"
"\n"
#: src/xz/message.c:1096
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"
#: src/xz/message.c:1100
msgid " Operation mode:\n"
msgstr " Operationsmodus:\n"
#: src/xz/message.c:1103
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
" -t, --test test compressed file integrity\n"
" -l, --list list information about .xz files"
msgstr ""
" -z, --compress erzwinge Komprimierung\n"
" -d, --decompress erzwinge Dekomprimierung\n"
" -t, --test überprüfe Datei Integrität\n"
" -l, --list liste Datei Informationen"
#: src/xz/message.c:1109
msgid ""
"\n"
" Operation modifiers:\n"
msgstr ""
"\n"
" Operationsmodifikatoren:\n"
#: src/xz/message.c:1112
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 Eingabedateien beibehalten (nicht löschen)\n"
" -f, --force erzwinge Überschreiben der Ausgabedatei und\n"
" (de)komprimiere Verweise (Links)\n"
" -c, --stdout schreibe nach Standard Output und lösche nicht die\n"
" Eingabedateien"
#: src/xz/message.c:1118
msgid ""
" --no-sparse do not create sparse files when decompressing\n"
" -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
" --files[=FILE] read filenames to process from FILE; if FILE is\n"
" omitted, filenames are read from the standard input;\n"
" filenames must be terminated with the newline "
"character\n"
" --files0[=FILE] like --files but use the null character as terminator"
msgstr ""
" --no-sparse erzeuge keine sparse Datei beim Dekomprimieren\n"
" -S, --suffix=.SUF benutze `.SUF' Endung für komprimierte Dateien\n"
" --files=[DATEI] lese zu verarbeitende Dateinamen von DATEI; falls\n"
" 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"
#: src/xz/message.c:1126
msgid ""
"\n"
" Basic file format and compression options:\n"
msgstr ""
"\n"
" Grundlegende Optionen für Dateiformat und Kompression:\n"
#: src/xz/message.c:1128
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 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"
" `crc64' (Voreinstellung), oder `sha256'"
#: src/xz/message.c:1135
msgid ""
" -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"
" Dekomprimierers, wenn Sie 7-9 benutzen!"
#: src/xz/message.c:1139
msgid ""
" -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"
" verhältnis zu verbessern. Das beeinflusst nicht den\n"
" Speicherbedarf des Dekomprimierers."
#: src/xz/message.c:1144
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
" set memory usage limit for compression, "
"decompression,\n"
" or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
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"
" oder 0 für Grundeinstellungen."
#: src/xz/message.c:1151
msgid ""
" --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"
" die Einstellungen nach unten anzupassen."
#: src/xz/message.c:1157
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
msgstr ""
"\n"
" User-definierte Filter Kette für Kompression (alternativ zu Voreinstellung):"
#: src/xz/message.c:1166
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
"or\n"
" --lzma2[=OPTS] more of the following options (valid values; "
"default):\n"
" preset=PRE reset options to a preset (0-9[e])\n"
" dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n"
" lc=NUM number of literal context bits (0-4; 3)\n"
" lp=NUM number of literal position bits (0-4; 0)\n"
" pb=NUM number of position bits (0-4; 2)\n"
" mode=MODE compression mode (fast, normal; normal)\n"
" nice=NUM nice length of a match (2-273; 64)\n"
" mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; "
"bt4)\n"
" depth=NUM maximum search depth; 0=automatic "
"(default)"
msgstr ""
"\n"
" --lzma1[=OPTIONEN] LZMA1 oder LZMA2; OPTIONEN ist eine durch Kommata\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"
" (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"
" pb=NUM Anzahl der Positionsbits (0-4; 2)\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"
" bt4)\n"
" depth=NUM Maximale Suchtiefe; 0=automatisch\n"
" (Voreinstellung)"
#: src/xz/message.c:1181
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
" --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n"
" --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n"
" --arm[=OPTS] ARM BCJ filter (little endian only)\n"
" --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n"
" --sparc[=OPTS] SPARC BCJ filter\n"
" Valid OPTS for all BCJ filters:\n"
" start=NUM start offset for conversions (default=0)"
msgstr ""
"\n"
" --x86[=OPTIONEN] x86 BCJ Filter (32-bit und 64-bit)\n"
" --powerpc[=OPTIONEN] PowerPC BCJ Filter (nur big endian)\n"
" --ia64[=OPTIONEN] IA64 (Itanium) BCJ Filter\n"
" --arm[=OPTIONEN] ARM BCJ Filter (nur little endian)\n"
" --armthumb[=OPTIONEN] ARM-Thumb BCJ Filter (nur little endian)\n"
" --sparc[=OPTIONEN] SPARC BCJ Filter\n"
" Zulässige Optionen für alle BCJ Filter:\n"
" start=NUM Start-Offset für Konversion\n"
" (Voreinstellung=0)"
#: src/xz/message.c:1193
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
" dist=NUM distance between bytes being subtracted\n"
" from each other (1-256; 1)"
msgstr ""
"\n"
" --delta[=OPTIONEN] Delta Filter; zulässige Optionen (gültige Werte;\n"
" Voreinstellung):\n"
" dist=NUM Abstand zwischen den Bytes, die "
"voneinander\n"
" subtrahiert werden (1-256; 1)"
#: src/xz/message.c:1201
msgid ""
"\n"
" Other options:\n"
msgstr ""
"\n"
" Andere Optionen:\n"
#: src/xz/message.c:1204
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors "
"too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
msgstr ""
" -q, --quiet 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"
" gesprächiger zu sein"
#: src/xz/message.c:1209
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:1211
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:1214
msgid ""
" --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:1217
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 zeige kurze Hilfe and (zeigt nur die grundlegenden\n"
" Optionen)\n"
" -H, --long-help zeige diese lange Hilfe an und terminiere"
#: src/xz/message.c:1221
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"
" Optionen an)"
#: src/xz/message.c:1226
msgid " -V, --version display the version number and exit"
msgstr " -V, --version zeige Versionsnummer an und terminiere"
#: src/xz/message.c:1228
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
msgstr ""
"\n"
"Wenn DATEI nicht angegeben wurde, oder DATEI gleich - ist, dann wird von\n"
"der Standardeingabe gelesen.\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:1234
#, 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"
#: src/xz/message.c:1236
#, c-format
msgid "%s home page: <%s>\n"
msgstr "%s Homepage: <%s>\n"
#: 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"
#: src/xz/options.c:93
#, c-format
msgid "%s: Invalid option name"
msgstr "%s: Ungültige Option"
#: src/xz/options.c:113
#, c-format
msgid "%s: Invalid option value"
msgstr "%s: Ungültiger Wert für Option"
#: src/xz/options.c:247
#, c-format
msgid "Unsupported LZMA1/LZMA2 preset: %s"
msgstr "LZMA1/LZMA2 Voreinstellung ist ungültig: %s"
#: src/xz/options.c:355
msgid "The sum of lc and lp must not exceed 4"
msgstr "Die Summe aus lc und lp darf höchstens 4 sein"
#: src/xz/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>"
#: src/xz/suffix.c:79 src/xz/suffix.c:164
#, 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"
#: src/xz/suffix.c:99
#, c-format
msgid "%s: Filename has an unknown suffix, skipping"
msgstr "%s: Dateiname hat unbekannte Endung, überspringe"
#: src/xz/suffix.c:154
#, c-format
msgid "%s: File already has `%s' suffix, skipping"
msgstr "%s: Datei hat bereits `%s' Endung, überspringe"
#: src/xz/suffix.c:205
#, c-format
msgid "%s: Invalid filename suffix"
msgstr "%s: Ungültige Datei Endung"
#: src/xz/util.c:61
#, c-format
msgid "%s: Value is not a non-negative decimal integer"
msgstr "%s: Wert ist keine nicht-negative ganze Zahl"
#: src/xz/util.c:103
#, c-format
msgid "%s: Invalid multiplier suffix"
msgstr "%s: Ungültige Einheit"
#: src/xz/util.c:105
msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
msgstr "Gültige Einheiten sind `KiB' (2^10), `MiB' (2^20), und `GiB' (2^30)."
#: src/xz/util.c:122
#, c-format
msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
msgstr "Wert der Option `%s' muss im Bereich [%<PRIu64>, %<PRIu64>] sein"
#: src/xz/util.c:247
msgid "Empty filename, skipping"
msgstr "Leere Dateiname, überspringe"
#: src/xz/util.c:261
msgid "Compressed data cannot be read from a terminal"
msgstr "Komprimierte Daten können nicht vom Terminal gelesen werden"
#: src/xz/util.c:274
msgid "Compressed data cannot be written to a terminal"
msgstr "Komprimierte Daten können nicht auf das Terminal geschrieben werden"
#: src/common/tuklib_exit.c:39
msgid "Writing to standard output failed"
msgstr "Schreiben auf die Standardausgabe fehlgeschlagen"
#: src/common/tuklib_exit.c:42
msgid "Unknown error"
msgstr "Unbekannter Fehler"

902
po/it.po Normal file
View File

@ -0,0 +1,902 @@
# Italian translation for xz-utils
# This file is in the public domain
# Gruppo traduzione italiano di Ubuntu-it <gruppo-traduzione@ubuntu-it.org>, 2009, 2010
# Lorenzo De Liso <blackz@ubuntu.com>, 2010.
# Milo Casagrande <milo@ubuntu.com>, 2009, 2010.
msgid ""
msgstr ""
"Project-Id-Version: xz-utils\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
"POT-Creation-Date: 2010-09-10 14:50+0300\n"
"PO-Revision-Date: 2010-09-16 21:32+0200\n"
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-08-16 19:16+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/xz/args.c:333
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: tipo di formato del file sconosciutoN"
#: src/xz/args.c:356 src/xz/args.c:364
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: tipo di controllo integrità non supportato"
#: src/xz/args.c:382
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:445
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "La variabile d'ambiente %s contiene troppi argomenti"
#: src/xz/coder.c:95
msgid "Maximum number of filters is four"
msgstr "Il numero massimo di filtri è quattro"
#: src/xz/coder.c:108
msgid "Memory usage limit is too low for the given filter setup."
msgstr ""
"Il limite dell'uso della memoria è troppo basso per l'impostazione del "
"filtro dato."
#: src/xz/coder.c:129
msgid "Using a preset in raw mode is discouraged."
msgstr "Non è consigliato usare un preset nella modalità raw."
#: src/xz/coder.c:131
msgid "The exact options of the presets may vary between software versions."
msgstr ""
"Le opzioni esatte per i preset possono variare tra le versioni del software."
#: src/xz/coder.c:157
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Il formato .lzma supporta solo il filtro LZMA1"
#: src/xz/coder.c:165
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 non può essere usato con il formato .xz"
#: src/xz/coder.c:182
msgid "Unsupported filter chain or filter options"
msgstr "Catena di filtri od opzioni del filtro non supportata"
#: src/xz/coder.c:190
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "L'estrazione necessita di %s MiB di memoria."
#: src/xz/coder.c:247
#, 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"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
#. if the source file still exists, and if it does, does its
#. device and inode numbers match what xz saw when it opened
#. the source file. If these checks fail, this message is
#. shown, %s being the filename, and the file is not deleted.
#. The check for device and inode numbers is there, because
#. it is possible that the user has put a new file in place
#. of the original file, and in that case it obviously
#. shouldn't be removed.
#: src/xz/file_io.c:137
#, 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:144 src/xz/file_io.c:590
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s: impossibile rimuovere: %s"
#: src/xz/file_io.c:169
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s: impossibile impostare il proprietario del file: %s"
#: src/xz/file_io.c:175
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s: impossibile impostare il gruppo del file: %s"
#: src/xz/file_io.c:194
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s: impossibile impostare i permessi del file: %s"
#: src/xz/file_io.c:337 src/xz/file_io.c:420
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s: è un collegamento simbolico, viene saltato"
#: src/xz/file_io.c:455
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s: è una directory, viene saltata"
#: src/xz/file_io.c:462
#, c-format
msgid "%s: Not a regular file, skipping"
msgstr "%s: non è un file regolare, viene saltato"
#: src/xz/file_io.c:479
#, 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:486
#, 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:493
#, 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:714
#, 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:726
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s: chiusura del file non riuscita: %s"
#: src/xz/file_io.c:762 src/xz/file_io.c:946
#, c-format
msgid "%s: Seeking failed when trying to create a sparse file: %s"
msgstr ""
"%s: posizionamento non riuscito nel tentativo di creare un file sparso: %s"
#: src/xz/file_io.c:821
#, c-format
msgid "%s: Read error: %s"
msgstr "%s: errore di lettura: %s"
#: src/xz/file_io.c:844
#, c-format
msgid "%s: Error seeking the file: %s"
msgstr "%s: errore nel cercare il file: %s"
#: src/xz/file_io.c:854
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s: fine del file inaspettata"
#: src/xz/file_io.c:904
#, c-format
msgid "%s: Write error: %s"
msgstr "%s: errore di scrittura: %s"
#: src/xz/hardware.c:100
msgid "Disabled"
msgstr "Disabilitato"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
#: src/xz/hardware.c:119
msgid "Total amount of physical memory (RAM): "
msgstr "Quantità totale di memoria fisica (RAM): "
#: src/xz/hardware.c:121
msgid "Memory usage limit for compression: "
msgstr "Limite utilizzo memoria per la compressione: "
#: src/xz/hardware.c:123
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
msgid "None"
msgstr "Nessuno"
#. TRANSLATORS: Indicates that integrity check name is not known,
#. but the Check ID is known (here 2). This and other "Unknown-N"
#. 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.
#: src/xz/list.c:69
msgid "Unknown-2"
msgstr "Sconosc2"
#: src/xz/list.c:70
msgid "Unknown-3"
msgstr "Sconosc3"
#: src/xz/list.c:72
msgid "Unknown-5"
msgstr "Sconosc5"
#: src/xz/list.c:73
msgid "Unknown-6"
msgstr "Sconosc6"
#: src/xz/list.c:74
msgid "Unknown-7"
msgstr "Sconosc7"
#: src/xz/list.c:75
msgid "Unknown-8"
msgstr "Sconosc8"
#: src/xz/list.c:76
msgid "Unknown-9"
msgstr "Sconosc9"
#: src/xz/list.c:78
msgid "Unknown-11"
msgstr "Sconosc11"
#: src/xz/list.c:79
msgid "Unknown-12"
msgstr "Sconosc12"
#: src/xz/list.c:80
msgid "Unknown-13"
msgstr "Sconosc13"
#: src/xz/list.c:81
msgid "Unknown-14"
msgstr "Sconosc14"
#: src/xz/list.c:82
msgid "Unknown-15"
msgstr "Sconosc15"
#: src/xz/list.c:126
#, c-format
msgid "%s: File is empty"
msgstr "%s: il file è vuoto"
#: src/xz/list.c:131
#, c-format
msgid "%s: Too small to be a valid .xz file"
msgstr "%s: troppo piccolo per essere un file .xz valido"
#. TRANSLATORS: These are column headings. From Strms (Streams)
#. to Ratio, the columns are right aligned. Check and Filename
#. are left aligned. If you need longer words, it's OK to
#. use two lines here. Test with "xz -l foo.xz".
#: src/xz/list.c:612
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr " Strm Blocc. Compresso Estratto Rapp. Contr Nome file"
#: src/xz/list.c:652
#, c-format
msgid " Streams: %s\n"
msgstr " Stream: %s\n"
#: src/xz/list.c:654
#, c-format
msgid " Blocks: %s\n"
msgstr " Blocchi: %s\n"
#: src/xz/list.c:656
#, c-format
msgid " Compressed size: %s\n"
msgstr " Dim. compresso: %s\n"
#: src/xz/list.c:659
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Dim. estratto: %s\n"
#: src/xz/list.c:662
#, c-format
msgid " Ratio: %s\n"
msgstr " Rapporto: %s\n"
#: src/xz/list.c:664
#, c-format
msgid " Check: %s\n"
msgstr " Controllo: %s\n"
#: src/xz/list.c:665
#, c-format
msgid " Stream padding: %s\n"
msgstr " Padding dello stream: %s\n"
#. 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
msgid ""
" Streams:\n"
" 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"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
#: src/xz/list.c:748
#, c-format
msgid ""
" Blocks:\n"
" Stream Block CompOffset UncompOffset TotalSize "
"UncompSize Ratio Check"
msgstr ""
" Blocchi:\n"
" 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
#. (Check value), Flags, and Filters are left aligned.
#. Header (Block Header Size), CompSize, and MemUsage
#. 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
#, 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
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Memoria necessaria: %s MiB\n"
#: src/xz/list.c:840 src/xz/list.c:1009
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Dim. negli header: %s\n"
#: src/xz/list.c:841 src/xz/list.c:1010
msgid "Yes"
msgstr "Sì"
#: src/xz/list.c:841 src/xz/list.c:1010
msgid "No"
msgstr "No"
#. 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
#, 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
msgid "Totals:"
msgstr "Totali:"
#: src/xz/list.c:1000
#, c-format
msgid " Number of files: %s\n"
msgstr " Numero di file: %s\n"
#: src/xz/list.c:1072
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
msgid "--list does not support reading from standard input"
msgstr "--list non è in grado di leggere dallo standard input"
#: 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
#, c-format
msgid "%s: Unexpected end of input when reading filenames"
msgstr "%s: fine dell'input durante la lettura dei nomi dei file non attesa"
#: src/xz/main.c: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\"?"
#: 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/message.c:800 src/xz/message.c:844
msgid "Internal error (bug)"
msgstr "Errore interno (bug)"
#: src/xz/message.c:807
msgid "Cannot establish signal handlers"
msgstr "Impossibile stabilire i gestori dei segnali"
#: src/xz/message.c:816
msgid "No integrity check; not verifying file integrity"
msgstr ""
"Nessun controllo d'integrità; l'integrità del file non viene verificata"
#: src/xz/message.c:819
msgid "Unsupported type of integrity check; not verifying file integrity"
msgstr ""
"Tipo di controllo di integrità non supportato; l'integrità del file non "
"viene verificata"
#: src/xz/message.c:826
msgid "Memory usage limit reached"
msgstr "Limite di utilizzo della memoria raggiunto"
#: src/xz/message.c:829
msgid "File format not recognized"
msgstr "Formato di file non riconosciuto"
#: src/xz/message.c:832
msgid "Unsupported options"
msgstr "Opzioni non supportate"
#: src/xz/message.c:835
msgid "Compressed data is corrupt"
msgstr "I dati compressi sono danneggiati"
#: src/xz/message.c:838
msgid "Unexpected end of input"
msgstr "Fine dell'input non attesa"
#: src/xz/message.c:886
#, 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:1053
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s: catena di filtri: %s\n"
#: src/xz/message.c:1063
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Provare \"%s --help\" per maggiori informazioni."
#: src/xz/message.c:1089
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
"Compress or decompress FILEs in the .xz format.\n"
"\n"
msgstr ""
"Uso: %s [OPZIONI]... [FILE]...\n"
"Comprime o estrae i FILE nel formato .xz.\n"
"\n"
#: src/xz/message.c:1096
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:1100
msgid " Operation mode:\n"
msgstr " Modalità di operazione:\n"
#: src/xz/message.c:1103
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
" -t, --test test compressed file integrity\n"
" -l, --list list information about .xz files"
msgstr ""
" -z, --compress Forza la compressione\n"
" -d, --decompress Forza l'estrazione\n"
" -t, --test Verifica l'integrità dei file compressi\n"
" -l, --list Elenca informazioni sui file .xz"
#: src/xz/message.c:1109
msgid ""
"\n"
" Operation modifiers:\n"
msgstr ""
"\n"
" Modificatori di operazioni:\n"
#: src/xz/message.c:1112
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"
" collegamenti\n"
" -c, --stdout Scrive sullo standard output e non elimina i file di "
"input"
#: src/xz/message.c:1118
msgid ""
" --no-sparse do not create sparse files when decompressing\n"
" -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
" --files[=FILE] read filenames to process from FILE; if FILE is\n"
" omitted, filenames are read from the standard input;\n"
" filenames must be terminated with the newline "
"character\n"
" --files0[=FILE] like --files but use the null character as terminator"
msgstr ""
" --no-sparse 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"
" di newline\n"
" --files0=[FILE] Come --files ma usa il carattere null come terminatore"
#: src/xz/message.c:1126
msgid ""
"\n"
" Basic file format and compression options:\n"
msgstr ""
"\n"
" Formato file di base e opzioni di compressione:\n"
#: src/xz/message.c:1128
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"
" \"crc32\", \"crc64\" (predefinito) o \"sha256\""
#: src/xz/message.c:1135
msgid ""
" -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"
" di usare 7-9"
#: src/xz/message.c:1139
msgid ""
" -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"
" memoria in fase di estrazione"
#: src/xz/message.c:1144
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
" set memory usage limit for compression, "
"decompression,\n"
" or both; LIMIT is in bytes, % of RAM, or 0 for defaults"
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"
" % della memoria RAM oppure 0 per il valore predefinito"
#: src/xz/message.c:1151
msgid ""
" --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"
" utilizzo della memoria, lancia un errore invece di\n"
" utilizzare valori più piccoli"
#: src/xz/message.c:1157
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
msgstr ""
"\n"
" Catena di filtri personalizzati per la compressione (alternative per\n"
" l'utilizzo di preset):"
#: src/xz/message.c:1166
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
"or\n"
" --lzma2[=OPTS] more of the following options (valid values; "
"default):\n"
" preset=PRE reset options to a preset (0-9[e])\n"
" dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n"
" lc=NUM number of literal context bits (0-4; 3)\n"
" lp=NUM number of literal position bits (0-4; 0)\n"
" pb=NUM number of position bits (0-4; 2)\n"
" mode=MODE compression mode (fast, normal; normal)\n"
" nice=NUM nice length of a match (2-273; 64)\n"
" mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; "
"bt4)\n"
" depth=NUM maximum search depth; 0=automatic "
"(default)"
msgstr ""
"\n"
" --lzma1[=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"
" pb=NUM Numero di bit di posizione (0-4; 2)\n"
" mode=MODE Modalità di compressione\n"
" (fast, normal; normal)\n"
" nice=NUM Lunghezza valida per una corrispondenza\n"
" (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"
" (predefinito)"
#: src/xz/message.c:1181
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
" --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n"
" --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n"
" --arm[=OPTS] ARM BCJ filter (little endian only)\n"
" --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n"
" --sparc[=OPTS] SPARC BCJ filter\n"
" Valid OPTS for all BCJ filters:\n"
" start=NUM start offset for conversions (default=0)"
msgstr ""
"\n"
" --x86[=OPZ] Filtro BCJ x86 (32 e 64 bit)\n"
" --powerpc[=OPZ] Filtro BCJ PowerPC (solo big endian)\n"
" --ia64[=OPZ] Filtro BCJ IA-64 (Itanium)\n"
" --arm[=OPZ] Filtro BCJ ARM (solo little endian)\n"
" --armthumb[=OPZ] Filtro BCJ ARM-Thumb (solo little endian)\n"
" --sparc[=OPZ] Filtro BCJ SPARC\n"
" OPZ valide per tutti i filtri BCJ:\n"
" start=NUM Offset iniziale per le conversioni\n"
" (predefinito=0)"
#: src/xz/message.c:1193
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
" dist=NUM distance between bytes being subtracted\n"
" from each other (1-256; 1)"
msgstr ""
"\n"
" --delta[=OPZ] Filtro Delta; OPZ valide (valori validi; predefinito):\n"
" dist=NUM Distanza tra byte sottratti\n"
" gli uni dagli altri (1-256; 1)"
#: src/xz/message.c:1201
msgid ""
"\n"
" Other options:\n"
msgstr ""
"\n"
" Altre opzioni:\n"
#: src/xz/message.c:1204
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors "
"too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
msgstr ""
" -q, --quiet Sopprime gli avvisi; specificare due volte per "
"sopprimere\n"
" anche gli errori\n"
" -v, --verbose Output prolisso; specificare due volte per output "
"ancora\n"
" più prolisso"
#: src/xz/message.c:1209
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:1211
msgid ""
" --robot use machine-parsable messages (useful for scripts)"
msgstr " --robot Usa messaggi analizzabili (utile per gli script)"
#: src/xz/message.c:1214
msgid ""
" --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"
" attivo di utilizzo della memore ed esce"
#: src/xz/message.c:1217
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 Stampa l'aiuto breve (elenca solo le opzioni di base)\n"
" -H, --long-help Stampa questo lungo aiuto ed esce"
#: src/xz/message.c:1221
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 Stampa questo breve aiuto ed esce\n"
" -H, --long-help Stampa l'aiuto lungo (elenca anche le opzioni avanzate)"
#: src/xz/message.c:1226
msgid " -V, --version display the version number and exit"
msgstr " -V, --version Stampa il numero della versione ed esce"
#: src/xz/message.c:1228
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
msgstr ""
"\n"
"Senza FILE, o quando FILE è -, legge lo standard input.\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:1234
#, 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:1236
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Sito web di %s: <%s>\n"
#: 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"
#: src/xz/options.c:93
#, c-format
msgid "%s: Invalid option name"
msgstr "%s: nome opzione non valido"
#: src/xz/options.c:113
#, c-format
msgid "%s: Invalid option value"
msgstr "%s: valore dell'opzione non valido"
#: 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
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
#, c-format
msgid "The selected match finder requires at least nice=%<PRIu32>"
msgstr ""
"Lo strumento per cercare corrispondenze selezionato richiede almeno nice=%"
"<PRIu32>"
#: src/xz/suffix.c:79 src/xz/suffix.c:164
#, 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"
#: src/xz/suffix.c:99
#, 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:154
#, 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:205
#, c-format
msgid "%s: Invalid filename suffix"
msgstr "%s: suffisso del nome del file non valido"
#: 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
#, c-format
msgid "%s: Invalid multiplier suffix"
msgstr "%s: suffisso del moltiplicatore non valido"
#: 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)."
#: 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>]"
#: src/xz/util.c:247
msgid "Empty filename, skipping"
msgstr "Nome file vuoto, viene saltato"
#: 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
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
msgid "Writing to standard output failed"
msgstr "Scrittura sullo standard ouput non riuscita"
#: src/common/tuklib_exit.c:42
msgid "Unknown error"
msgstr "Errore sconosciuto"

View File

@ -102,11 +102,11 @@
# elif SIZEOF_SIZE_T == 8
# define SIZE_MAX UINT64_MAX
# else
# error sizeof(size_t) is not 32-bit or 64-bit
# error size_t is not 32-bit or 64-bit
# endif
#endif
#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX
# error sizeof(size_t) is not 32-bit or 64-bit
# error size_t is not 32-bit or 64-bit
#endif
#include <stdlib.h>
@ -156,13 +156,11 @@ typedef unsigned char _Bool;
#undef memzero
#define memzero(s, n) memset(s, 0, n)
#ifndef MIN
# define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif
#ifndef MAX
# define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif
// NOTE: Avoid using MIN() and MAX(), because even conditionally defining
// those macros can cause some portability trouble, since on some systems
// the system headers insist defining their own versions.
#define my_min(x, y) ((x) < (y) ? (x) : (y))
#define my_max(x, y) ((x) > (y) ? (x) : (y))
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))

View File

@ -20,6 +20,11 @@
#elif defined(TUKLIB_CPUCORES_SYSCONF)
# include <unistd.h>
// HP-UX
#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
# include <sys/param.h>
# include <sys/pstat.h>
#endif
@ -34,7 +39,7 @@ tuklib_cpucores(void)
size_t cpus_size = sizeof(cpus);
if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
&& cpus_size == sizeof(cpus) && cpus > 0)
ret = (uint32_t)cpus;
ret = cpus;
#elif defined(TUKLIB_CPUCORES_SYSCONF)
# ifdef _SC_NPROCESSORS_ONLN
@ -45,7 +50,12 @@ tuklib_cpucores(void)
const long cpus = sysconf(_SC_NPROC_ONLN);
# endif
if (cpus > 0)
ret = (uint32_t)cpus;
ret = cpus;
#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
struct pst_dynamic pst;
if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
ret = pst.psd_proc_cnt;
#endif
return ret;

View File

@ -33,12 +33,12 @@
textdomain(package); \
} while (0)
# define _(msgid) gettext(msgid)
# define N_(msgid1, msgid2, n) ngettext(msgid1, msgid2, n)
#else
# define tuklib_gettext_init(package, localedir) \
setlocale(LC_ALL, "")
# define _(msgid) (msgid)
# define N_(msgid1, msgid2, n) ((n) == 1 ? (msgid1) : (msgid2))
# define ngettext(msgid1, msgid2, n) ((n) == 1 ? (msgid1) : (msgid2))
#endif
#define N_(msgid) msgid
#endif

66
src/common/tuklib_mbstr.h Normal file
View File

@ -0,0 +1,66 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file tuklib_mstr.h
/// \brief Utility functions for handling multibyte strings
///
/// If not enough multibyte string support is available in the C library,
/// these functions keep working with the assumption that all strings
/// are in a single-byte character set without combining characters, e.g.
/// US-ASCII or ISO-8859-*.
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef TUKLIB_MBSTR_H
#define TUKLIB_MBSTR_H
#include "tuklib_common.h"
TUKLIB_DECLS_BEGIN
#define tuklib_mbstr_width TUKLIB_SYMBOL(tuklib_mbstr_width)
extern size_t tuklib_mbstr_width(const char *str, size_t *bytes);
///<
/// \brief Get the number of columns needed for the multibyte string
///
/// This is somewhat similar to wcswidth() but works on multibyte strings.
///
/// \param str String whose width is to be calculated. If the
/// current locale uses a multibyte character set
/// that has shift states, the string must begin
/// and end in the initial shift state.
/// \param bytes If this is not NULL, *bytes is set to the
/// value returned by strlen(str) (even if an
/// error occurs when calculating the width).
///
/// \return On success, the number of columns needed to display the
/// string e.g. in a terminal emulator is returned. On error,
/// (size_t)-1 is returned. Possible errors include invalid,
/// partial, or non-printable multibyte character in str, or
/// that str doesn't end in the initial shift state.
#define tuklib_mbstr_fw TUKLIB_SYMBOL(tuklib_mbstr_fw)
extern int tuklib_mbstr_fw(const char *str, int columns_min);
///<
/// \brief Get the field width for printf() e.g. to align table columns
///
/// Printing simple tables to a terminal can be done using the field field
/// feature in the printf() format string, but it works only with single-byte
/// character sets. To do the same with multibyte strings, tuklib_mbstr_fw()
/// can be used to calculate appropriate field width.
///
/// The behavior of this function is undefined, if
/// - str is NULL or not terminated with '\0';
/// - columns_min <= 0; or
/// - the calculated field width exceeds INT_MAX.
///
/// \return If tuklib_mbstr_width(str, NULL) fails, -1 is returned.
/// If str needs more columns than columns_min, zero is returned.
/// Otherwise a positive integer is returned, which can be
/// used as the field width, e.g. printf("%*s", fw, str).
TUKLIB_DECLS_END
#endif

View File

@ -0,0 +1,31 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file tuklib_mstr_fw.c
/// \brief Get the field width for printf() e.g. to align table columns
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "tuklib_mbstr.h"
extern int
tuklib_mbstr_fw(const char *str, int columns_min)
{
size_t len;
const size_t width = tuklib_mbstr_width(str, &len);
if (width == (size_t)-1)
return -1;
if (width > (size_t)columns_min)
return 0;
if (width < (size_t)columns_min)
len += (size_t)columns_min - width;
return len;
}

View File

@ -0,0 +1,64 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file tuklib_mstr_width.c
/// \brief Calculate width of a multibyte string
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "tuklib_mbstr.h"
#if defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
# include <wchar.h>
#endif
extern size_t
tuklib_mbstr_width(const char *str, size_t *bytes)
{
const size_t len = strlen(str);
if (bytes != NULL)
*bytes = len;
#if !(defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH))
// In single-byte mode, the width of the string is the same
// as its length.
return len;
#else
mbstate_t state;
memset(&state, 0, sizeof(state));
size_t width = 0;
size_t i = 0;
// Convert one multibyte character at a time to wchar_t
// and get its width using wcwidth().
while (i < len) {
wchar_t wc;
const size_t ret = mbrtowc(&wc, str + i, len - i, &state);
if (ret < 1 || ret > len)
return (size_t)-1;
i += ret;
const int wc_width = wcwidth(wc);
if (wc_width < 0)
return (size_t)-1;
width += wc_width;
}
// Require that the string ends in the initial shift state.
// This way the caller can be combine the string with other
// strings without needing to worry about the shift states.
if (!mbsinit(&state))
return (size_t)-1;
return width;
#endif
}

View File

@ -33,6 +33,10 @@
# include <syidef.h>
# include <ssdef.h>
// AIX
#elif defined(TUKLIB_PHYSMEM_AIX)
# include <sys/systemcfg.h>
#elif defined(TUKLIB_PHYSMEM_SYSCONF)
# include <unistd.h>
@ -42,6 +46,16 @@
# endif
# include <sys/sysctl.h>
// Tru64
#elif defined(TUKLIB_PHYSMEM_GETSYSINFO)
# include <sys/sysinfo.h>
# include <machine/hal_sysinfo.h>
// HP-UX
#elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
# include <sys/param.h>
# include <sys/pstat.h>
// IRIX
#elif defined(TUKLIB_PHYSMEM_GETINVENT_R)
# include <invent.h>
@ -105,10 +119,13 @@ tuklib_physmem(void)
if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)
ret = (uint64_t)vms_mem * 8192;
#elif defined(TUKLIB_PHYSMEM_AIX)
ret = _system_configuration.physmem;
#elif defined(TUKLIB_PHYSMEM_SYSCONF)
const long pagesize = sysconf(_SC_PAGESIZE);
const long pages = sysconf(_SC_PHYS_PAGES);
if (pagesize != -1 || pages != -1)
if (pagesize != -1 && pages != -1)
// According to docs, pagesize * pages can overflow.
// Simple case is 32-bit box with 4 GiB or more RAM,
// which may report exactly 4 GiB of RAM, and "long"
@ -140,6 +157,20 @@ tuklib_physmem(void)
ret = mem.u32;
}
#elif defined(TUKLIB_PHYSMEM_GETSYSINFO)
// Docs are unclear if "start" is needed, but it doesn't hurt
// much to have it.
int memkb;
int start = 0;
if (getsysinfo(GSI_PHYSMEM, (caddr_t)&memkb, sizeof(memkb), &start)
!= -1)
ret = (uint64_t)memkb * 1024;
#elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)
struct pst_static pst;
if (pstat_getstatic(&pst, sizeof(pst), 1, 0) != -1)
ret = (uint64_t)pst.physical_memory * (uint64_t)pst.page_size;
#elif defined(TUKLIB_PHYSMEM_GETINVENT_R)
inv_state_t *st = NULL;
if (setinvent_r(&st) != -1) {

View File

@ -232,10 +232,6 @@
#if __GNUC__ >= 3
# ifndef lzma_attribute
# define lzma_attribute(attr) __attribute__(attr)
# endif
# ifndef lzma_restrict
# define lzma_restrict __restrict__
# endif
/* warn_unused_result was added in GCC 3.4. */
@ -249,14 +245,6 @@
# ifndef lzma_attribute
# define lzma_attribute(attr)
# endif
# ifndef lzma_restrict
# if __STDC_VERSION__ >= 199901L
# define lzma_restrict restrict
# else
# define lzma_restrict
# endif
# endif
#endif
@ -296,7 +284,6 @@ extern "C" {
/* Filters */
#include "lzma/filter.h"
#include "lzma/subblock.h"
#include "lzma/bcj.h"
#include "lzma/delta.h"
#include "lzma/lzma.h"

View File

@ -368,7 +368,7 @@ extern LZMA_API(lzma_ret) lzma_index_stream_flags(
/**
* \brief Get the types of integrity Checks
*
* If lzma_index_stream_padding() is used to set the Stream Flags for
* If lzma_index_stream_flags() is used to set the Stream Flags for
* every Stream, lzma_index_checks() can be used to get a bitmask to
* indicate which Check types have been used. It can be useful e.g. if
* showing the Check types to the user.
@ -562,9 +562,8 @@ extern LZMA_API(lzma_bool) lzma_index_iter_locate(
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *lzma_restrict dest,
lzma_index *lzma_restrict src,
lzma_allocator *allocator)
extern LZMA_API(lzma_ret) lzma_index_cat(
lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
lzma_nothrow lzma_attr_warn_unused_result;

View File

@ -49,7 +49,7 @@
* The memory usage formulas are only rough estimates, which are closest to
* reality when dict_size is a power of two. The formulas are more complex
* in reality, and can also change a little between liblzma versions. Use
* lzma_memusage_encoder() to get more accurate estimate of memory usage.
* lzma_raw_encoder_memusage() to get more accurate estimate of memory usage.
*/
typedef enum {
LZMA_MF_HC3 = 0x03,
@ -69,7 +69,9 @@ typedef enum {
*
* Minimum nice_len: 4
*
* Memory usage: dict_size * 7.5
* Memory usage:
* - dict_size <= 32 MiB: dict_size * 7.5
* - dict_size > 32 MiB: dict_size * 6.5
*/
LZMA_MF_BT2 = 0x12,
@ -98,7 +100,9 @@ typedef enum {
*
* Minimum nice_len: 4
*
* Memory usage: dict_size * 11.5
* Memory usage:
* - dict_size <= 32 MiB: dict_size * 11.5
* - dict_size > 32 MiB: dict_size * 10.5
*/
} lzma_match_finder;

View File

@ -1,200 +0,0 @@
/**
* \file lzma/subblock.h
* \brief Subblock filter
*/
/*
* Author: Lasse Collin
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
*
* See ../lzma.h for information about liblzma as a whole.
*/
#ifndef LZMA_H_INTERNAL
# error Never include this file directly. Use <lzma.h> instead.
#endif
/**
* \brief Filter ID
*
* Filter ID of the Subblock filter. This is used as lzma_filter.id.
*/
#define LZMA_FILTER_SUBBLOCK LZMA_VLI_C(0x01)
/**
* \brief Subfilter mode
*
* See lzma_options_subblock.subfilter_mode for details.
*/
typedef enum {
LZMA_SUBFILTER_NONE,
/**<
* No Subfilter is in use.
*/
LZMA_SUBFILTER_SET,
/**<
* New Subfilter has been requested to be initialized.
*/
LZMA_SUBFILTER_RUN,
/**<
* Subfilter is active.
*/
LZMA_SUBFILTER_FINISH
/**<
* Subfilter has been requested to be finished.
*/
} lzma_subfilter_mode;
/**
* \brief Options for the Subblock filter
*
* Specifying options for the Subblock filter is optional: if the pointer
* options is NULL, no subfilters are allowed and the default value is used
* for subblock_data_size.
*/
typedef struct {
/* Options for encoder and decoder */
/**
* \brief Allowing subfilters
*
* If this true, subfilters are allowed.
*
* In the encoder, if this is set to false, subfilter_mode and
* subfilter_options are completely ignored.
*/
lzma_bool allow_subfilters;
/* Options for encoder only */
/**
* \brief Alignment
*
* The Subblock filter encapsulates the input data into Subblocks.
* Each Subblock has a header which takes a few bytes of space.
* When the output of the Subblock encoder is fed to another filter
* that takes advantage of the alignment of the input data (e.g. LZMA),
* the Subblock filter can add padding to keep the actual data parts
* in the Subblocks aligned correctly.
*
* The alignment should be a positive integer. Subblock filter will
* add enough padding between Subblocks so that this is true for
* every payload byte:
* input_offset % alignment == output_offset % alignment
*
* The Subblock filter assumes that the first output byte will be
* written to a position in the output stream that is properly
* aligned. This requirement is automatically met when the start
* offset of the Stream or Block is correctly told to Block or
* Stream encoder.
*/
uint32_t alignment;
# define LZMA_SUBBLOCK_ALIGNMENT_MIN 1
# define LZMA_SUBBLOCK_ALIGNMENT_MAX 32
# define LZMA_SUBBLOCK_ALIGNMENT_DEFAULT 4
/**
* \brief Size of the Subblock Data part of each Subblock
*
* This value is re-read every time a new Subblock is started.
*
* Bigger values
* - save a few bytes of space;
* - increase latency in the encoder (but no effect for decoding);
* - decrease memory locality (increased cache pollution) in the
* encoder (no effect in decoding).
*/
uint32_t subblock_data_size;
# define LZMA_SUBBLOCK_DATA_SIZE_MIN 1
# define LZMA_SUBBLOCK_DATA_SIZE_MAX (UINT32_C(1) << 28)
# define LZMA_SUBBLOCK_DATA_SIZE_DEFAULT 4096
/**
* \brief Run-length encoder remote control
*
* The Subblock filter has an internal run-length encoder (RLE). It
* can be useful when the data includes byte sequences that repeat
* very many times. The RLE can be used also when a Subfilter is
* in use; the RLE will be applied to the output of the Subfilter.
*
* Note that in contrast to traditional RLE, this RLE is intended to
* be used only when there's a lot of data to be repeated. If the
* input data has e.g. 500 bytes of NULs now and then, this RLE
* is probably useless, because plain LZMA should provide better
* results.
*
* Due to above reasons, it was decided to keep the implementation
* of the RLE very simple. When the rle variable is non-zero, it
* subblock_data_size must be a multiple of rle. Once the Subblock
* encoder has got subblock_data_size bytes of input, it will check
* if the whole buffer of the last subblock_data_size can be
* represented with repeats of chunks having size of rle bytes.
*
* If there are consecutive identical buffers of subblock_data_size
* bytes, they will be encoded using a single repeat entry if
* possible.
*
* If need arises, more advanced RLE can be implemented later
* without breaking API or ABI.
*/
uint32_t rle;
# define LZMA_SUBBLOCK_RLE_OFF 0
# define LZMA_SUBBLOCK_RLE_MIN 1
# define LZMA_SUBBLOCK_RLE_MAX 256
/**
* \brief Subfilter remote control
*
* When the Subblock filter is initialized, this variable must be
* LZMA_SUBFILTER_NONE or LZMA_SUBFILTER_SET.
*
* When subfilter_mode is LZMA_SUBFILTER_NONE, the application may
* put Subfilter options to subfilter_options structure, and then
* set subfilter_mode to LZMA_SUBFILTER_SET. No new input data will
* be read until the Subfilter has been enabled. Once the Subfilter
* has been enabled, liblzma will set subfilter_mode to
* LZMA_SUBFILTER_RUN.
*
* When subfilter_mode is LZMA_SUBFILTER_RUN, the application may
* set subfilter_mode to LZMA_SUBFILTER_FINISH. All the input
* currently available will be encoded before unsetting the
* Subfilter. Application must not change the amount of available
* input until the Subfilter has finished. Once the Subfilter has
* finished, liblzma will set subfilter_mode to LZMA_SUBFILTER_NONE.
*
* If the intent is to have Subfilter enabled to the very end of
* the data, it is not needed to separately disable Subfilter with
* LZMA_SUBFILTER_FINISH. Using LZMA_FINISH as the second argument
* of lzma_code() will make the Subblock encoder to disable the
* Subfilter once all the data has been ran through the Subfilter.
*
* After the first call with LZMA_SYNC_FLUSH or LZMA_FINISH, the
* application must not change subfilter_mode until LZMA_STREAM_END.
* Setting LZMA_SUBFILTER_SET/LZMA_SUBFILTER_FINISH and
* LZMA_SYNC_FLUSH/LZMA_FINISH _at the same time_ is fine.
*
* \note This variable is ignored if allow_subfilters is false.
*/
lzma_subfilter_mode subfilter_mode;
/**
* \brief Subfilter and its options
*
* When no Subfilter is used, the data is copied as is into Subblocks.
* Setting a Subfilter allows encoding some parts of the data with
* an additional filter. It is possible to many different Subfilters
* in the same Block, although only one can be used at once.
*
* \note This variable is ignored if allow_subfilters is false.
*/
lzma_filter subfilter_options;
} lzma_options_subblock;

View File

@ -113,9 +113,8 @@ typedef uint64_t lzma_vli;
* - LZMA_BUF_ERROR: No output space was provided.
* - LZMA_PROG_ERROR: Arguments are not sane.
*/
extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli,
size_t *vli_pos, uint8_t *lzma_restrict out,
size_t *lzma_restrict out_pos, size_t out_size) lzma_nothrow;
extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos,
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
/**
@ -153,9 +152,9 @@ extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli,
* - LZMA_BUF_ERROR: No input was provided.
* - LZMA_PROG_ERROR: Arguments are not sane.
*/
extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *lzma_restrict vli,
size_t *vli_pos, const uint8_t *lzma_restrict in,
size_t *lzma_restrict in_pos, size_t in_size) lzma_nothrow;
extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow;
/**

View File

@ -139,7 +139,7 @@ block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,
// Size of the uncompressed chunk
const size_t copy_size
= MIN(in_size - in_pos, LZMA2_CHUNK_MAX);
= my_min(in_size - in_pos, LZMA2_CHUNK_MAX);
out[(*out_pos)++] = (copy_size - 1) >> 8;
out[(*out_pos)++] = (copy_size - 1) & 0xFF;

View File

@ -15,7 +15,7 @@
extern LZMA_API(lzma_ret)
lzma_block_compressed_size(lzma_block *block, lzma_vli total_size)
lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)
{
// Validate everything but Uncompressed Size and filters.
if (lzma_block_unpadded_size(block) == 0)
@ -25,13 +25,13 @@ lzma_block_compressed_size(lzma_block *block, lzma_vli total_size)
+ lzma_check_size(block->check);
// Validate that Compressed Size will be greater than zero.
if (container_size <= total_size)
if (unpadded_size <= container_size)
return LZMA_DATA_ERROR;
// Calculate what Compressed Size is supposed to be.
// If Compressed Size was present in Block Header,
// compare that the new value matches it.
const lzma_vli compressed_size = total_size - container_size;
const lzma_vli compressed_size = unpadded_size - container_size;
if (block->compressed_size != LZMA_VLI_UNKNOWN
&& block->compressed_size != compressed_size)
return LZMA_DATA_ERROR;

View File

@ -1,67 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file chunk_size.c
/// \brief Finds out the minimal reasonable chunk size for a filter chain
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "common.h"
/**
* \brief Finds out the minimal reasonable chunk size for a filter chain
*
* This function helps determining the Uncompressed Sizes of the Blocks when
* doing multi-threaded encoding.
*
* When compressing a large file on a system having multiple CPUs or CPU
* cores, the file can be split into smaller chunks, that are compressed
* independently into separate Blocks in the same .lzma Stream.
*
* \return Minimum reasonable Uncompressed Size of a Block. The
* recommended minimum Uncompressed Size is between this value
* and the value times two.
Zero if the Uncompressed Sizes of Blocks don't matter
*/
extern LZMA_API(size_t)
lzma_chunk_size(const lzma_options_filter *filters)
{
while (filters->id != LZMA_VLI_UNKNOWN) {
switch (filters->id) {
// TODO LZMA_FILTER_SPARSE
case LZMA_FILTER_COPY:
case LZMA_FILTER_SUBBLOCK:
case LZMA_FILTER_X86:
case LZMA_FILTER_POWERPC:
case LZMA_FILTER_IA64:
case LZMA_FILTER_ARM:
case LZMA_FILTER_ARMTHUMB:
case LZMA_FILTER_SPARC:
// These are very fast, thus there is no point in
// splitting the data into smaller blocks.
break;
case LZMA_FILTER_LZMA1:
// The block sizes of the possible next filters in
// the chain are irrelevant after the LZMA filter.
return ((lzma_options_lzma *)(filters->options))
->dictionary_size;
default:
// Unknown filters
return 0;
}
++filters;
}
// Indicate that splitting would be useless.
return SIZE_MAX;
}

View File

@ -76,7 +76,7 @@ lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
{
const size_t in_avail = in_size - *in_pos;
const size_t out_avail = out_size - *out_pos;
const size_t copy_size = MIN(in_avail, out_avail);
const size_t copy_size = my_min(in_avail, out_avail);
memcpy(out + *out_pos, in + *in_pos, copy_size);

View File

@ -60,12 +60,6 @@
#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
/// Internal helper filter used by Subblock decoder. It is mapped to an
/// otherwise invalid Filter ID, which is impossible to get from any input
/// file (even if malicious file).
#define LZMA_FILTER_SUBBLOCK_HELPER LZMA_VLI_C(0x7000000000000001)
/// Supported flags that can be passed to lzma_stream_decoder()
/// or lzma_auto_decoder().
#define LZMA_SUPPORTED_FLAGS \

View File

@ -52,15 +52,6 @@ static const struct {
.changes_size = true,
},
#endif
#if defined(HAVE_ENCODER_SUBBLOCK) || defined(HAVE_DECODER_SUBBLOCK)
{
.id = LZMA_FILTER_SUBBLOCK,
.options_size = sizeof(lzma_options_subblock),
.non_last_ok = true,
.last_ok = true,
.changes_size = true,
},
#endif
#ifdef HAVE_DECODER_X86
{
.id = LZMA_FILTER_X86,

View File

@ -14,8 +14,6 @@
#include "filter_common.h"
#include "lzma_decoder.h"
#include "lzma2_decoder.h"
#include "subblock_decoder.h"
#include "subblock_decoder_helper.h"
#include "simple_decoder.h"
#include "delta_decoder.h"
@ -60,20 +58,6 @@ static const lzma_filter_decoder decoders[] = {
.props_decode = &lzma_lzma2_props_decode,
},
#endif
#ifdef HAVE_DECODER_SUBBLOCK
{
.id = LZMA_FILTER_SUBBLOCK,
.init = &lzma_subblock_decoder_init,
// .memusage = &lzma_subblock_decoder_memusage,
.props_decode = NULL,
},
{
.id = LZMA_FILTER_SUBBLOCK_HELPER,
.init = &lzma_subblock_decoder_helper_init,
.memusage = NULL,
.props_decode = NULL,
},
#endif
#ifdef HAVE_DECODER_X86
{
.id = LZMA_FILTER_X86,

View File

@ -14,7 +14,6 @@
#include "filter_common.h"
#include "lzma_encoder.h"
#include "lzma2_encoder.h"
#include "subblock_encoder.h"
#include "simple_encoder.h"
#include "delta_encoder.h"
@ -77,17 +76,6 @@ static const lzma_filter_encoder encoders[] = {
.props_encode = &lzma_lzma2_props_encode,
},
#endif
#ifdef HAVE_ENCODER_SUBBLOCK
{
.id = LZMA_FILTER_SUBBLOCK,
.init = &lzma_subblock_encoder_init,
// .memusage = &lzma_subblock_encoder_memusage,
.chunk_size = NULL,
.props_size_get = NULL,
.props_size_fixed = 0,
.props_encode = NULL,
},
#endif
#ifdef HAVE_ENCODER_X86
{
.id = LZMA_FILTER_X86,

View File

@ -33,7 +33,7 @@ lzma_stream_buffer_bound(size_t uncompressed_size)
// Catch the possible integer overflow and also prevent the size of
// the Stream exceeding LZMA_VLI_MAX (theoretically possible on
// 64-bit systems).
if (MIN(SIZE_MAX, LZMA_VLI_MAX) - block_bound < HEADERS_BOUND)
if (my_min(SIZE_MAX, LZMA_VLI_MAX) - block_bound < HEADERS_BOUND)
return 0;
return block_bound + HEADERS_BOUND;

View File

@ -59,7 +59,7 @@ delta_encode(lzma_coder *coder, lzma_allocator *allocator,
if (coder->next.code == NULL) {
const size_t in_avail = in_size - *in_pos;
const size_t out_avail = out_size - *out_pos;
const size_t size = MIN(in_avail, out_avail);
const size_t size = my_min(in_avail, out_avail);
copy_and_encode(coder, in + *in_pos, out + *out_pos, size);

View File

@ -81,8 +81,9 @@ decode_buffer(lzma_coder *coder,
// It must not decode past the end of the dictionary
// buffer, and we don't want it to decode more than is
// actually needed to fill the out[] buffer.
coder->dict.limit = coder->dict.pos + MIN(out_size - *out_pos,
coder->dict.size - coder->dict.pos);
coder->dict.limit = coder->dict.pos
+ my_min(out_size - *out_pos,
coder->dict.size - coder->dict.pos);
// Call the coder->lz.code() to do the actual decoding.
const lzma_ret ret = coder->lz.code(
@ -264,7 +265,7 @@ lzma_lz_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
&& lz_options.preset_dict_size > 0) {
// If the preset dictionary is bigger than the actual
// dictionary, copy only the tail.
const size_t copy_size = MIN(lz_options.preset_dict_size,
const size_t copy_size = my_min(lz_options.preset_dict_size,
lz_options.dict_size);
const size_t offset = lz_options.preset_dict_size - copy_size;
memcpy(next->coder->dict.buf, lz_options.preset_dict + offset,

View File

@ -129,7 +129,7 @@ dict_repeat(lzma_dict *dict, uint32_t distance, uint32_t *len)
{
// Don't write past the end of the dictionary.
const size_t dict_avail = dict->limit - dict->pos;
uint32_t left = MIN(dict_avail, *len);
uint32_t left = my_min(dict_avail, *len);
*len -= left;
// Repeat a block of data from the history. Because memcpy() is faster

View File

@ -341,7 +341,7 @@ lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
// Deallocate the old hash array if it exists and has different size
// than what is needed now.
if (mf->hash != NULL && old_count != new_count) {
if (old_count != new_count) {
lzma_free(mf->hash, allocator);
mf->hash = NULL;
}
@ -349,9 +349,10 @@ lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
// Maximum number of match finder cycles
mf->depth = lz_options->depth;
if (mf->depth == 0) {
mf->depth = 16 + (mf->nice_len / 2);
if (!is_bt)
mf->depth /= 2;
if (is_bt)
mf->depth = 16 + mf->nice_len / 2;
else
mf->depth = 4 + mf->nice_len / 4;
}
return false;
@ -423,7 +424,7 @@ lz_encoder_init(lzma_mf *mf, lzma_allocator *allocator,
&& lz_options->preset_dict_size > 0) {
// If the preset dictionary is bigger than the actual
// dictionary, use only the tail.
mf->write_pos = MIN(lz_options->preset_dict_size, mf->size);
mf->write_pos = my_min(lz_options->preset_dict_size, mf->size);
memcpy(mf->buffer, lz_options->preset_dict
+ lz_options->preset_dict_size - mf->write_pos,
mf->write_pos);
@ -444,6 +445,8 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
lzma_mf mf = {
.buffer = NULL,
.hash = NULL,
.hash_size_sum = 0,
.sons_count = 0,
};
// Setup the size information into mf.
@ -519,6 +522,8 @@ lzma_lz_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
next->coder->mf.buffer = NULL;
next->coder->mf.hash = NULL;
next->coder->mf.hash_size_sum = 0;
next->coder->mf.sons_count = 0;
next->coder->next = LZMA_NEXT_CODER_INIT;
}

View File

@ -281,7 +281,7 @@ mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size,
size_t *left)
{
const size_t out_avail = out_size - *out_pos;
const size_t copy_size = MIN(out_avail, *left);
const size_t copy_size = my_min(out_avail, *left);
assert(mf->read_ahead == 0);
assert(mf->read_pos >= *left);

View File

@ -481,7 +481,7 @@ bt_find_func(
<< 1);
const uint8_t *const pb = cur - delta;
uint32_t len = MIN(len0, len1);
uint32_t len = my_min(len0, len1);
if (pb[len] == cur[len]) {
while (++len != len_limit)
@ -546,7 +546,7 @@ bt_skip_func(
+ (delta > cyclic_pos ? cyclic_size : 0))
<< 1);
const uint8_t *pb = cur - delta;
uint32_t len = MIN(len0, len1);
uint32_t len = my_min(len0, len1);
if (pb[len] == cur[len]) {
while (++len != len_limit)

View File

@ -372,7 +372,7 @@ extern lzma_ret
lzma_lzma2_props_encode(const void *options, uint8_t *out)
{
const lzma_options_lzma *const opt = options;
uint32_t d = MAX(opt->dict_size, LZMA_DICT_SIZE_MIN);
uint32_t d = my_max(opt->dict_size, LZMA_DICT_SIZE_MIN);
// Round up to to the next 2^n - 1 or 2^n + 2^(n - 1) - 1 depending
// on which one is the next:

View File

@ -33,7 +33,7 @@ lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf,
}
const uint8_t *buf = mf_ptr(mf) - 1;
const uint32_t buf_avail = MIN(mf_avail(mf) + 1, MATCH_LEN_MAX);
const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
if (buf_avail < 2) {
// There's not enough input left to encode a match.

View File

@ -287,7 +287,7 @@ helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
matches_count = coder->matches_count;
}
const uint32_t buf_avail = MIN(mf_avail(mf) + 1, MATCH_LEN_MAX);
const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
if (buf_avail < 2) {
*back_res = UINT32_MAX;
*len_res = 1;
@ -371,7 +371,7 @@ helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
}
}
const uint32_t len_end = MAX(len_main, rep_lens[rep_max_index]);
const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);
if (len_end < 2) {
*back_res = coder->opts[1].back_prev;
@ -565,12 +565,12 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
if (buf_avail_full < 2)
return len_end;
const uint32_t buf_avail = MIN(buf_avail_full, nice_len);
const uint32_t buf_avail = my_min(buf_avail_full, nice_len);
if (!next_is_literal && match_byte != current_byte) { // speed optimization
// try literal + rep0
const uint8_t *const buf_back = buf - reps[0] - 1;
const uint32_t limit = MIN(buf_avail_full, nice_len + 1);
const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
uint32_t len_test = 1;
while (len_test < limit && buf[len_test] == buf_back[len_test])
@ -648,7 +648,7 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
uint32_t len_test_2 = len_test + 1;
const uint32_t limit = MIN(buf_avail_full,
const uint32_t limit = my_min(buf_avail_full,
len_test_2 + nice_len);
for (; len_test_2 < limit
&& buf[len_test_2] == buf_back[len_test_2];
@ -743,7 +743,7 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
// Try Match + Literal + Rep0
const uint8_t *const buf_back = buf - cur_back - 1;
uint32_t len_test_2 = len_test + 1;
const uint32_t limit = MIN(buf_avail_full,
const uint32_t limit = my_min(buf_avail_full,
len_test_2 + nice_len);
for (; len_test_2 < limit &&
@ -860,7 +860,7 @@ lzma_lzma_optimum_normal(lzma_coder *restrict coder, lzma_mf *restrict mf,
len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,
position + cur, cur, mf->nice_len,
MIN(mf_avail(mf) + 1, OPTS - 1 - cur));
my_min(mf_avail(mf) + 1, OPTS - 1 - cur));
}
backward(coder, len_res, back_res, cur);

View File

@ -23,9 +23,6 @@ lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
if (level > 9 || (flags & ~supported_flags))
return true;
const uint32_t dict_shift = level <= 1 ? 16 : level + 17;
options->dict_size = UINT32_C(1) << dict_shift;
options->preset_dict = NULL;
options->preset_dict_size = 0;
@ -33,19 +30,31 @@ lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
options->lp = LZMA_LP_DEFAULT;
options->pb = LZMA_PB_DEFAULT;
options->mode = level <= 2 ? LZMA_MODE_FAST : LZMA_MODE_NORMAL;
options->dict_size = UINT32_C(1) << (uint8_t []){
18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }[level];
options->nice_len = level == 0 ? 8 : level <= 5 ? 32 : 64;
options->mf = level <= 1 ? LZMA_MF_HC3 : level <= 2 ? LZMA_MF_HC4
: LZMA_MF_BT4;
options->depth = 0;
if (flags & LZMA_PRESET_EXTREME) {
options->lc = 4; // FIXME?
if (level <= 3) {
options->mode = LZMA_MODE_FAST;
options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4;
options->nice_len = level <= 1 ? 128 : 273;
options->depth = (uint8_t []){ 4, 8, 24, 48 }[level];
} else {
options->mode = LZMA_MODE_NORMAL;
options->mf = LZMA_MF_BT4;
options->nice_len = 273;
options->depth = 512;
options->nice_len = level == 4 ? 16 : level == 5 ? 32 : 64;
options->depth = 0;
}
if (flags & LZMA_PRESET_EXTREME) {
options->mode = LZMA_MODE_NORMAL;
options->mf = LZMA_MF_BT4;
if (level == 3 || level == 5) {
options->nice_len = 192;
options->depth = 0;
} else {
options->nice_len = 273;
options->depth = 512;
}
}
return false;

View File

@ -1,630 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_decoder.c
/// \brief Decoder of the Subblock filter
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "subblock_decoder.h"
#include "subblock_decoder_helper.h"
#include "filter_decoder.h"
/// Maximum number of consecutive Subblocks with Subblock Type Padding
#define PADDING_MAX 31
struct lzma_coder_s {
lzma_next_coder next;
enum {
// These require that there is at least one input
// byte available.
SEQ_FLAGS,
SEQ_FILTER_FLAGS,
SEQ_FILTER_END,
SEQ_REPEAT_COUNT_1,
SEQ_REPEAT_COUNT_2,
SEQ_REPEAT_COUNT_3,
SEQ_REPEAT_SIZE,
SEQ_REPEAT_READ_DATA,
SEQ_SIZE_1,
SEQ_SIZE_2,
SEQ_SIZE_3, // This must be right before SEQ_DATA.
// These don't require any input to be available.
SEQ_DATA,
SEQ_REPEAT_FAST,
SEQ_REPEAT_NORMAL,
} sequence;
/// Number of bytes left in the current Subblock Data field.
size_t size;
/// Number of consecutive Subblocks with Subblock Type Padding
uint32_t padding;
/// True when .next.code() has returned LZMA_STREAM_END.
bool next_finished;
/// True when the Subblock decoder has detected End of Payload Marker.
/// This may become true before next_finished becomes true.
bool this_finished;
/// True if Subfilters are allowed.
bool allow_subfilters;
/// Indicates if at least one byte of decoded output has been
/// produced after enabling Subfilter.
bool got_output_with_subfilter;
/// Possible subfilter
lzma_next_coder subfilter;
/// Filter Flags decoder is needed to parse the ID and Properties
/// of the subfilter.
lzma_next_coder filter_flags_decoder;
/// The filter_flags_decoder stores its results here.
lzma_filter filter_flags;
/// Options for the Subblock decoder helper. This is used to tell
/// the helper when it should return LZMA_STREAM_END to the subfilter.
lzma_options_subblock_helper helper;
struct {
/// How many times buffer should be repeated
size_t count;
/// Size of the buffer
size_t size;
/// Position in the buffer
size_t pos;
/// Buffer to hold the data to be repeated
uint8_t buffer[LZMA_SUBBLOCK_RLE_MAX];
} repeat;
/// Temporary buffer needed when the Subblock filter is not the last
/// filter in the chain. The output of the next filter is first
/// decoded into buffer[], which is then used as input for the actual
/// Subblock decoder.
struct {
size_t pos;
size_t size;
uint8_t buffer[LZMA_BUFFER_SIZE];
} temp;
};
/// Values of valid Subblock Flags
enum {
FLAG_PADDING,
FLAG_EOPM,
FLAG_DATA,
FLAG_REPEAT,
FLAG_SET_SUBFILTER,
FLAG_END_SUBFILTER,
};
/// Calls the subfilter and updates coder->uncompressed_size.
static lzma_ret
subfilter_decode(lzma_coder *coder, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
assert(coder->subfilter.code != NULL);
// Call the subfilter.
const lzma_ret ret = coder->subfilter.code(
coder->subfilter.coder, allocator,
in, in_pos, in_size, out, out_pos, out_size, action);
return ret;
}
static lzma_ret
decode_buffer(lzma_coder *coder, lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
while (*out_pos < out_size && (*in_pos < in_size
|| coder->sequence >= SEQ_DATA))
switch (coder->sequence) {
case SEQ_FLAGS: {
// Do the correct action depending on the Subblock Type.
switch (in[*in_pos] >> 4) {
case FLAG_PADDING:
// Only check that reserved bits are zero.
if (++coder->padding > PADDING_MAX
|| in[*in_pos] & 0x0F)
return LZMA_DATA_ERROR;
++*in_pos;
break;
case FLAG_EOPM:
// There must be no Padding before EOPM.
if (coder->padding != 0)
return LZMA_DATA_ERROR;
// Check that reserved bits are zero.
if (in[*in_pos] & 0x0F)
return LZMA_DATA_ERROR;
// There must be no Subfilter enabled.
if (coder->subfilter.code != NULL)
return LZMA_DATA_ERROR;
++*in_pos;
return LZMA_STREAM_END;
case FLAG_DATA:
// First four bits of the Subblock Data size.
coder->size = in[*in_pos] & 0x0F;
++*in_pos;
coder->got_output_with_subfilter = true;
coder->sequence = SEQ_SIZE_1;
break;
case FLAG_REPEAT:
// First four bits of the Repeat Count. We use
// coder->size as a temporary place for it.
coder->size = in[*in_pos] & 0x0F;
++*in_pos;
coder->got_output_with_subfilter = true;
coder->sequence = SEQ_REPEAT_COUNT_1;
break;
case FLAG_SET_SUBFILTER: {
if (coder->padding != 0 || (in[*in_pos] & 0x0F)
|| coder->subfilter.code != NULL
|| !coder->allow_subfilters)
return LZMA_DATA_ERROR;
assert(coder->filter_flags.options == NULL);
abort();
// return_if_error(lzma_filter_flags_decoder_init(
// &coder->filter_flags_decoder,
// allocator, &coder->filter_flags));
coder->got_output_with_subfilter = false;
++*in_pos;
coder->sequence = SEQ_FILTER_FLAGS;
break;
}
case FLAG_END_SUBFILTER: {
if (coder->padding != 0 || (in[*in_pos] & 0x0F)
|| coder->subfilter.code == NULL
|| !coder->got_output_with_subfilter)
return LZMA_DATA_ERROR;
// Tell the helper filter to indicate End of Input
// to our subfilter.
coder->helper.end_was_reached = true;
size_t dummy = 0;
const lzma_ret ret = subfilter_decode(coder, allocator,
NULL, &dummy, 0, out, out_pos,out_size,
action);
// If we didn't reach the end of the subfilter's output
// yet, return to the application. On the next call we
// will get to this same switch-case again, because we
// haven't updated *in_pos yet.
if (ret != LZMA_STREAM_END)
return ret;
// Free Subfilter's memory. This is a bit debatable,
// since we could avoid some malloc()/free() calls
// if the same Subfilter gets used soon again. But
// if Subfilter isn't used again, we could leave
// a memory-hogging filter dangling until someone
// frees Subblock filter itself.
lzma_next_end(&coder->subfilter, allocator);
// Free memory used for subfilter options. This is
// safe, because we don't support any Subfilter that
// would allow pointers in the options structure.
lzma_free(coder->filter_flags.options, allocator);
coder->filter_flags.options = NULL;
++*in_pos;
break;
}
default:
return LZMA_DATA_ERROR;
}
break;
}
case SEQ_FILTER_FLAGS: {
const lzma_ret ret = coder->filter_flags_decoder.code(
coder->filter_flags_decoder.coder, allocator,
in, in_pos, in_size, NULL, NULL, 0, LZMA_RUN);
if (ret != LZMA_STREAM_END)
return ret == LZMA_OPTIONS_ERROR
? LZMA_DATA_ERROR : ret;
// Don't free the filter_flags_decoder. It doesn't take much
// memory and we may need it again.
// Initialize the Subfilter. Subblock and Copy filters are
// not allowed.
if (coder->filter_flags.id == LZMA_FILTER_SUBBLOCK)
return LZMA_DATA_ERROR;
coder->helper.end_was_reached = false;
lzma_filter filters[3] = {
{
.id = coder->filter_flags.id,
.options = coder->filter_flags.options,
}, {
.id = LZMA_FILTER_SUBBLOCK_HELPER,
.options = &coder->helper,
}, {
.id = LZMA_VLI_UNKNOWN,
.options = NULL,
}
};
// Optimization: We know that LZMA uses End of Payload Marker
// (not End of Input), so we can omit the helper filter.
if (filters[0].id == LZMA_FILTER_LZMA1)
filters[1].id = LZMA_VLI_UNKNOWN;
return_if_error(lzma_raw_decoder_init(
&coder->subfilter, allocator, filters));
coder->sequence = SEQ_FLAGS;
break;
}
case SEQ_FILTER_END:
// We are in the beginning of a Subblock. The next Subblock
// whose type is not Padding, must indicate end of Subfilter.
if (in[*in_pos] == (FLAG_PADDING << 4)) {
++*in_pos;
break;
}
if (in[*in_pos] != (FLAG_END_SUBFILTER << 4))
return LZMA_DATA_ERROR;
coder->sequence = SEQ_FLAGS;
break;
case SEQ_REPEAT_COUNT_1:
case SEQ_SIZE_1:
// We use the same code to parse
// - the Size (28 bits) in Subblocks of type Data; and
// - the Repeat count (28 bits) in Subblocks of type
// Repeating Data.
coder->size |= (size_t)(in[*in_pos]) << 4;
++*in_pos;
++coder->sequence;
break;
case SEQ_REPEAT_COUNT_2:
case SEQ_SIZE_2:
coder->size |= (size_t)(in[*in_pos]) << 12;
++*in_pos;
++coder->sequence;
break;
case SEQ_REPEAT_COUNT_3:
case SEQ_SIZE_3:
coder->size |= (size_t)(in[*in_pos]) << 20;
++*in_pos;
// The real value is the stored value plus one.
++coder->size;
// This moves to SEQ_REPEAT_SIZE or SEQ_DATA. That's why
// SEQ_DATA must be right after SEQ_SIZE_3 in coder->sequence.
++coder->sequence;
break;
case SEQ_REPEAT_SIZE:
// Move the Repeat Count to the correct variable and parse
// the Size of the Data to be repeated.
coder->repeat.count = coder->size;
coder->repeat.size = (size_t)(in[*in_pos]) + 1;
coder->repeat.pos = 0;
// The size of the Data field must be bigger than the number
// of Padding bytes before this Subblock.
if (coder->repeat.size <= coder->padding)
return LZMA_DATA_ERROR;
++*in_pos;
coder->padding = 0;
coder->sequence = SEQ_REPEAT_READ_DATA;
break;
case SEQ_REPEAT_READ_DATA: {
// Fill coder->repeat.buffer[].
const size_t in_avail = in_size - *in_pos;
const size_t out_avail
= coder->repeat.size - coder->repeat.pos;
const size_t copy_size = MIN(in_avail, out_avail);
memcpy(coder->repeat.buffer + coder->repeat.pos,
in + *in_pos, copy_size);
*in_pos += copy_size;
coder->repeat.pos += copy_size;
if (coder->repeat.pos == coder->repeat.size) {
coder->repeat.pos = 0;
if (coder->repeat.size == 1
&& coder->subfilter.code == NULL)
coder->sequence = SEQ_REPEAT_FAST;
else
coder->sequence = SEQ_REPEAT_NORMAL;
}
break;
}
case SEQ_DATA: {
// The size of the Data field must be bigger than the number
// of Padding bytes before this Subblock.
assert(coder->size > 0);
if (coder->size <= coder->padding)
return LZMA_DATA_ERROR;
coder->padding = 0;
// Limit the amount of input to match the available
// Subblock Data size.
size_t in_limit;
if (in_size - *in_pos > coder->size)
in_limit = *in_pos + coder->size;
else
in_limit = in_size;
if (coder->subfilter.code == NULL) {
const size_t copy_size = lzma_bufcpy(
in, in_pos, in_limit,
out, out_pos, out_size);
coder->size -= copy_size;
} else {
const size_t in_start = *in_pos;
const lzma_ret ret = subfilter_decode(
coder, allocator,
in, in_pos, in_limit,
out, out_pos, out_size,
action);
// Update the number of unprocessed bytes left in
// this Subblock. This assert() is true because
// in_limit prevents *in_pos getting too big.
assert(*in_pos - in_start <= coder->size);
coder->size -= *in_pos - in_start;
if (ret == LZMA_STREAM_END) {
// End of Subfilter can occur only at
// a Subblock boundary.
if (coder->size != 0)
return LZMA_DATA_ERROR;
// We need a Subblock with Unset
// Subfilter before more data.
coder->sequence = SEQ_FILTER_END;
break;
}
if (ret != LZMA_OK)
return ret;
}
// If we couldn't process the whole Subblock Data yet, return.
if (coder->size > 0)
return LZMA_OK;
coder->sequence = SEQ_FLAGS;
break;
}
case SEQ_REPEAT_FAST: {
// Optimization for cases when there is only one byte to
// repeat and no Subfilter.
const size_t out_avail = out_size - *out_pos;
const size_t copy_size = MIN(coder->repeat.count, out_avail);
memset(out + *out_pos, coder->repeat.buffer[0], copy_size);
*out_pos += copy_size;
coder->repeat.count -= copy_size;
if (coder->repeat.count != 0)
return LZMA_OK;
coder->sequence = SEQ_FLAGS;
break;
}
case SEQ_REPEAT_NORMAL:
do {
// Cycle the repeat buffer if needed.
if (coder->repeat.pos == coder->repeat.size) {
if (--coder->repeat.count == 0) {
coder->sequence = SEQ_FLAGS;
break;
}
coder->repeat.pos = 0;
}
if (coder->subfilter.code == NULL) {
lzma_bufcpy(coder->repeat.buffer,
&coder->repeat.pos,
coder->repeat.size,
out, out_pos, out_size);
} else {
const lzma_ret ret = subfilter_decode(
coder, allocator,
coder->repeat.buffer,
&coder->repeat.pos,
coder->repeat.size,
out, out_pos, out_size,
action);
if (ret == LZMA_STREAM_END) {
// End of Subfilter can occur only at
// a Subblock boundary.
if (coder->repeat.pos
!= coder->repeat.size
|| --coder->repeat
.count != 0)
return LZMA_DATA_ERROR;
// We need a Subblock with Unset
// Subfilter before more data.
coder->sequence = SEQ_FILTER_END;
break;
} else if (ret != LZMA_OK) {
return ret;
}
}
} while (*out_pos < out_size);
break;
default:
return LZMA_PROG_ERROR;
}
return LZMA_OK;
}
static lzma_ret
subblock_decode(lzma_coder *coder, lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
if (coder->next.code == NULL)
return decode_buffer(coder, allocator, in, in_pos, in_size,
out, out_pos, out_size, action);
while (*out_pos < out_size) {
if (!coder->next_finished
&& coder->temp.pos == coder->temp.size) {
coder->temp.pos = 0;
coder->temp.size = 0;
const lzma_ret ret = coder->next.code(
coder->next.coder,
allocator, in, in_pos, in_size,
coder->temp.buffer, &coder->temp.size,
LZMA_BUFFER_SIZE, action);
if (ret == LZMA_STREAM_END)
coder->next_finished = true;
else if (coder->temp.size == 0 || ret != LZMA_OK)
return ret;
}
if (coder->this_finished) {
if (coder->temp.pos != coder->temp.size)
return LZMA_DATA_ERROR;
if (coder->next_finished)
return LZMA_STREAM_END;
return LZMA_OK;
}
const lzma_ret ret = decode_buffer(coder, allocator,
coder->temp.buffer, &coder->temp.pos,
coder->temp.size,
out, out_pos, out_size, action);
if (ret == LZMA_STREAM_END)
// The next coder in the chain hasn't finished
// yet. If the input data is valid, there
// must be no more output coming, but the
// next coder may still need a litle more
// input to detect End of Payload Marker.
coder->this_finished = true;
else if (ret != LZMA_OK)
return ret;
else if (coder->next_finished && *out_pos < out_size)
return LZMA_DATA_ERROR;
}
return LZMA_OK;
}
static void
subblock_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
lzma_next_end(&coder->next, allocator);
lzma_next_end(&coder->subfilter, allocator);
lzma_next_end(&coder->filter_flags_decoder, allocator);
lzma_free(coder->filter_flags.options, allocator);
lzma_free(coder, allocator);
return;
}
extern lzma_ret
lzma_subblock_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter_info *filters)
{
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
next->code = &subblock_decode;
next->end = &subblock_decoder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
next->coder->subfilter = LZMA_NEXT_CODER_INIT;
next->coder->filter_flags_decoder = LZMA_NEXT_CODER_INIT;
} else {
lzma_next_end(&next->coder->subfilter, allocator);
lzma_free(next->coder->filter_flags.options, allocator);
}
next->coder->filter_flags.options = NULL;
next->coder->sequence = SEQ_FLAGS;
next->coder->padding = 0;
next->coder->next_finished = false;
next->coder->this_finished = false;
next->coder->temp.pos = 0;
next->coder->temp.size = 0;
if (filters[0].options != NULL)
next->coder->allow_subfilters = ((lzma_options_subblock *)(
filters[0].options))->allow_subfilters;
else
next->coder->allow_subfilters = false;
return lzma_next_filter_init(
&next->coder->next, allocator, filters + 1);
}

View File

@ -1,22 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_decoder.h
/// \brief Decoder of the Subblock filter
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_SUBBLOCK_DECODER_H
#define LZMA_SUBBLOCK_DECODER_H
#include "common.h"
extern lzma_ret lzma_subblock_decoder_init(lzma_next_coder *next,
lzma_allocator *allocator, const lzma_filter_info *filters);
#endif

View File

@ -1,70 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_decoder_helper.c
/// \brief Helper filter for the Subblock decoder
///
/// This filter is used to indicate End of Input for subfilters needing it.
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "subblock_decoder_helper.h"
struct lzma_coder_s {
const lzma_options_subblock_helper *options;
};
static lzma_ret
helper_decode(lzma_coder *coder,
lzma_allocator *allocator lzma_attribute((unused)),
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action lzma_attribute((unused)))
{
// If end_was_reached is true, we cannot have any input.
assert(!coder->options->end_was_reached || *in_pos == in_size);
// We can safely copy as much as possible, because we are never
// given more data than a single Subblock Data field.
lzma_bufcpy(in, in_pos, in_size, out, out_pos, out_size);
// Return LZMA_STREAM_END when instructed so by the Subblock decoder.
return coder->options->end_was_reached ? LZMA_STREAM_END : LZMA_OK;
}
static void
helper_end(lzma_coder *coder, lzma_allocator *allocator)
{
lzma_free(coder, allocator);
return;
}
extern lzma_ret
lzma_subblock_decoder_helper_init(lzma_next_coder *next,
lzma_allocator *allocator, const lzma_filter_info *filters)
{
// This is always the last filter in the chain.
assert(filters[1].init == NULL);
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
next->code = &helper_decode;
next->end = &helper_end;
}
next->coder->options = filters[0].options;
return LZMA_OK;
}

View File

@ -1,29 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_decoder_helper.h
/// \brief Helper filter for the Subblock decoder
///
/// This filter is used to indicate End of Input for subfilters needing it.
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_SUBBLOCK_DECODER_HELPER_H
#define LZMA_SUBBLOCK_DECODER_HELPER_H
#include "common.h"
typedef struct {
bool end_was_reached;
} lzma_options_subblock_helper;
extern lzma_ret lzma_subblock_decoder_helper_init(lzma_next_coder *next,
lzma_allocator *allocator, const lzma_filter_info *filters);
#endif

View File

@ -1,984 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_encoder.c
/// \brief Encoder of the Subblock filter
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "subblock_encoder.h"
#include "filter_encoder.h"
/// Maximum number of repeats that a single Repeating Data can indicate.
/// This is directly from the file format specification.
#define REPEAT_COUNT_MAX (1U << 28)
/// Number of bytes the data chunk (not including the header part) must be
/// before we care about alignment. This is somewhat arbitrary. It just
/// doesn't make sense to waste bytes for alignment when the data chunk
/// is very small.
#define MIN_CHUNK_SIZE_FOR_ALIGN 4
/// Number of bytes of the header part of Subblock Type `Data'. This is
/// used as the `skew' argument for subblock_align().
#define ALIGN_SKEW_DATA 4
/// Like above but for Repeating Data.
#define ALIGN_SKEW_REPEATING_DATA 5
/// Writes one byte to output buffer and updates the alignment counter.
#define write_byte(b) \
do { \
assert(*out_pos < out_size); \
out[*out_pos] = b; \
++*out_pos; \
++coder->alignment.out_pos; \
} while (0)
struct lzma_coder_s {
lzma_next_coder next;
bool next_finished;
enum {
SEQ_FILL,
SEQ_FLUSH,
SEQ_RLE_COUNT_0,
SEQ_RLE_COUNT_1,
SEQ_RLE_COUNT_2,
SEQ_RLE_COUNT_3,
SEQ_RLE_SIZE,
SEQ_RLE_DATA,
SEQ_DATA_SIZE_0,
SEQ_DATA_SIZE_1,
SEQ_DATA_SIZE_2,
SEQ_DATA_SIZE_3,
SEQ_DATA,
SEQ_SUBFILTER_INIT,
SEQ_SUBFILTER_FLAGS,
} sequence;
/// Pointer to the options given by the application. This is used
/// for two-way communication with the application.
lzma_options_subblock *options;
/// Position in various arrays.
size_t pos;
/// Holds subblock.size - 1 or rle.size - 1 when encoding size
/// of Data or Repeat Count.
uint32_t tmp;
struct {
/// This is a copy of options->alignment, or
/// LZMA_SUBBLOCK_ALIGNMENT_DEFAULT if options is NULL.
uint32_t multiple;
/// Number of input bytes which we have processed and started
/// writing out. 32-bit integer is enough since we care only
/// about the lowest bits when fixing alignment.
uint32_t in_pos;
/// Number of bytes written out.
uint32_t out_pos;
} alignment;
struct {
/// Pointer to allocated buffer holding the Data field
/// of Subblock Type "Data".
uint8_t *data;
/// Number of bytes in the buffer.
size_t size;
/// Allocated size of the buffer.
size_t limit;
/// Number of input bytes that we have already read but
/// not yet started writing out. This can be different
/// to `size' when using Subfilter. That's why we track
/// in_pending separately for RLE (see below).
uint32_t in_pending;
} subblock;
struct {
/// Buffer to hold the data that may be coded with
/// Subblock Type `Repeating Data'.
uint8_t buffer[LZMA_SUBBLOCK_RLE_MAX];
/// Number of bytes in buffer[].
size_t size;
/// Number of times the first `size' bytes of buffer[]
/// will be repeated.
uint64_t count;
/// Like subblock.in_pending above, but for RLE.
uint32_t in_pending;
} rle;
struct {
enum {
SUB_NONE,
SUB_SET,
SUB_RUN,
SUB_FLUSH,
SUB_FINISH,
SUB_END_MARKER,
} mode;
/// This is a copy of options->allow_subfilters. We use
/// this to verify that the application doesn't change
/// the value of allow_subfilters.
bool allow;
/// When this is true, application is not allowed to modify
/// options->subblock_mode. We may still modify it here.
bool mode_locked;
/// True if we have encoded at least one byte of data with
/// the Subfilter.
bool got_input;
/// Track the amount of input available once
/// LZMA_SUBFILTER_FINISH has been enabled.
/// This is needed for sanity checking (kind
/// of duplicating what common/code.c does).
size_t in_avail;
/// Buffer for the Filter Flags field written after
/// the `Set Subfilter' indicator.
uint8_t *flags;
/// Size of Filter Flags field.
uint32_t flags_size;
/// Pointers to Subfilter.
lzma_next_coder subcoder;
} subfilter;
/// Temporary buffer used when we are not the last filter in the chain.
struct {
size_t pos;
size_t size;
uint8_t buffer[LZMA_BUFFER_SIZE];
} temp;
};
/// \brief Aligns the output buffer
///
/// Aligns the output buffer so that after skew bytes the output position is
/// a multiple of coder->alignment.multiple.
static bool
subblock_align(lzma_coder *coder, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
size_t chunk_size, uint32_t skew)
{
assert(*out_pos < out_size);
// Fix the alignment only if it makes sense at least a little.
if (chunk_size >= MIN_CHUNK_SIZE_FOR_ALIGN) {
const uint32_t target = coder->alignment.in_pos
% coder->alignment.multiple;
while ((coder->alignment.out_pos + skew)
% coder->alignment.multiple != target) {
// Zero indicates padding.
write_byte(0x00);
// Check if output buffer got full and indicate it to
// the caller.
if (*out_pos == out_size)
return true;
}
}
// Output buffer is not full.
return false;
}
/// \brief Checks if buffer contains repeated data
///
/// \param needle Buffer containing a single repeat chunk
/// \param needle_size Size of needle in bytes
/// \param buf Buffer to search for repeated needles
/// \param buf_chunks Buffer size is buf_chunks * needle_size.
///
/// \return True if the whole buf is filled with repeated needles.
///
static bool
is_repeating(const uint8_t *restrict needle, size_t needle_size,
const uint8_t *restrict buf, size_t buf_chunks)
{
while (buf_chunks-- != 0) {
if (memcmp(buf, needle, needle_size) != 0)
return false;
buf += needle_size;
}
return true;
}
/// \brief Optimizes the repeating style and updates coder->sequence
static void
subblock_rle_flush(lzma_coder *coder)
{
// The Subblock decoder can use memset() when the size of the data
// being repeated is one byte, so we check if the RLE buffer is
// filled with a single repeating byte.
if (coder->rle.size > 1) {
const uint8_t b = coder->rle.buffer[0];
size_t i = 0;
while (true) {
if (coder->rle.buffer[i] != b)
break;
if (++i == coder->rle.size) {
// TODO Integer overflow check maybe,
// although this needs at least 2**63 bytes
// of input until it gets triggered...
coder->rle.count *= coder->rle.size;
coder->rle.size = 1;
break;
}
}
}
if (coder->rle.count == 1) {
// The buffer should be repeated only once. It is
// waste of space to use Repeating Data. Instead,
// write a regular Data Subblock. See SEQ_RLE_COUNT_0
// in subblock_buffer() for more info.
coder->tmp = coder->rle.size - 1;
} else if (coder->rle.count > REPEAT_COUNT_MAX) {
// There's so much to repeat that it doesn't fit into
// 28-bit integer. We will write two or more Subblocks
// of type Repeating Data.
coder->tmp = REPEAT_COUNT_MAX - 1;
} else {
coder->tmp = coder->rle.count - 1;
}
coder->sequence = SEQ_RLE_COUNT_0;
return;
}
/// \brief Resizes coder->subblock.data for a new size limit
static lzma_ret
subblock_data_size(lzma_coder *coder, lzma_allocator *allocator,
size_t new_limit)
{
// Verify that the new limit is valid.
if (new_limit < LZMA_SUBBLOCK_DATA_SIZE_MIN
|| new_limit > LZMA_SUBBLOCK_DATA_SIZE_MAX)
return LZMA_OPTIONS_ERROR;
// Ff the new limit is different than the previous one, we need
// to reallocate the data buffer.
if (new_limit != coder->subblock.limit) {
lzma_free(coder->subblock.data, allocator);
coder->subblock.data = lzma_alloc(new_limit, allocator);
if (coder->subblock.data == NULL)
return LZMA_MEM_ERROR;
}
coder->subblock.limit = new_limit;
return LZMA_OK;
}
static lzma_ret
subblock_buffer(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)
{
// Changing allow_subfilter is not allowed.
if (coder->options != NULL && coder->subfilter.allow
!= coder->options->allow_subfilters)
return LZMA_PROG_ERROR;
// Check if we need to do something special with the Subfilter.
if (coder->subfilter.allow) {
assert(coder->options != NULL);
// See if subfilter_mode has been changed.
switch (coder->options->subfilter_mode) {
case LZMA_SUBFILTER_NONE:
if (coder->subfilter.mode != SUB_NONE)
return LZMA_PROG_ERROR;
break;
case LZMA_SUBFILTER_SET:
if (coder->subfilter.mode_locked
|| coder->subfilter.mode != SUB_NONE)
return LZMA_PROG_ERROR;
coder->subfilter.mode = SUB_SET;
coder->subfilter.got_input = false;
if (coder->sequence == SEQ_FILL)
coder->sequence = SEQ_FLUSH;
break;
case LZMA_SUBFILTER_RUN:
if (coder->subfilter.mode != SUB_RUN)
return LZMA_PROG_ERROR;
break;
case LZMA_SUBFILTER_FINISH: {
const size_t in_avail = in_size - *in_pos;
if (coder->subfilter.mode == SUB_RUN) {
if (coder->subfilter.mode_locked)
return LZMA_PROG_ERROR;
coder->subfilter.mode = SUB_FINISH;
coder->subfilter.in_avail = in_avail;
} else if (coder->subfilter.mode != SUB_FINISH
|| coder->subfilter.in_avail
!= in_avail) {
return LZMA_PROG_ERROR;
}
break;
}
default:
return LZMA_OPTIONS_ERROR;
}
// If we are sync-flushing or finishing, the application may
// no longer change subfilter_mode. Note that this check is
// done after checking the new subfilter_mode above; this
// way the application may e.g. set LZMA_SUBFILTER_SET and
// LZMA_SYNC_FLUSH at the same time, but it cannot modify
// subfilter_mode on the later lzma_code() calls before
// we have returned LZMA_STREAM_END.
if (action != LZMA_RUN)
coder->subfilter.mode_locked = true;
}
// Main loop
while (*out_pos < out_size)
switch (coder->sequence) {
case SEQ_FILL:
// Grab the new Subblock Data Size and reallocate the buffer.
if (coder->subblock.size == 0 && coder->options != NULL
&& coder->options->subblock_data_size
!= coder->subblock.limit)
return_if_error(subblock_data_size(coder,
allocator, coder->options
->subblock_data_size));
if (coder->subfilter.mode == SUB_NONE) {
assert(coder->subfilter.subcoder.code == NULL);
// No Subfilter is enabled, just copy the data as is.
coder->subblock.in_pending += lzma_bufcpy(
in, in_pos, in_size,
coder->subblock.data,
&coder->subblock.size,
coder->subblock.limit);
// If we ran out of input before the whole buffer
// was filled, return to application.
if (coder->subblock.size < coder->subblock.limit
&& action == LZMA_RUN)
return LZMA_OK;
} else {
assert(coder->options->subfilter_mode
!= LZMA_SUBFILTER_SET);
// Using LZMA_FINISH automatically toggles
// LZMA_SUBFILTER_FINISH.
//
// NOTE: It is possible that application had set
// LZMA_SUBFILTER_SET and LZMA_FINISH at the same
// time. In that case it is possible that we will
// cycle to LZMA_SUBFILTER_RUN, LZMA_SUBFILTER_FINISH,
// and back to LZMA_SUBFILTER_NONE in a single
// Subblock encoder function call.
if (action == LZMA_FINISH) {
coder->options->subfilter_mode
= LZMA_SUBFILTER_FINISH;
coder->subfilter.mode = SUB_FINISH;
}
const size_t in_start = *in_pos;
const lzma_ret ret = coder->subfilter.subcoder.code(
coder->subfilter.subcoder.coder,
allocator, in, in_pos, in_size,
coder->subblock.data,
&coder->subblock.size,
coder->subblock.limit,
coder->subfilter.mode == SUB_FINISH
? LZMA_FINISH : action);
const size_t in_used = *in_pos - in_start;
coder->subblock.in_pending += in_used;
if (in_used > 0)
coder->subfilter.got_input = true;
coder->subfilter.in_avail = in_size - *in_pos;
if (ret == LZMA_STREAM_END) {
// All currently available input must have
// been processed.
assert(*in_pos == in_size);
// Flush now. Even if coder->subblock.size
// happened to be zero, we still need to go
// to SEQ_FLUSH to possibly finish RLE or
// write the Subfilter Unset indicator.
coder->sequence = SEQ_FLUSH;
if (coder->subfilter.mode == SUB_RUN) {
// Flushing with Subfilter enabled.
assert(action == LZMA_SYNC_FLUSH);
coder->subfilter.mode = SUB_FLUSH;
break;
}
// Subfilter finished its job.
assert(coder->subfilter.mode == SUB_FINISH
|| action == LZMA_FINISH);
// At least one byte of input must have been
// encoded with the Subfilter. This is
// required by the file format specification.
if (!coder->subfilter.got_input)
return LZMA_PROG_ERROR;
// We don't strictly need to do this, but
// doing it sounds like a good idea, because
// otherwise the Subfilter's memory could be
// left allocated for long time, and would
// just waste memory.
lzma_next_end(&coder->subfilter.subcoder,
allocator);
// We need to flush the currently buffered
// data and write Unset Subfilter marker.
// Note that we cannot set
// coder->options->subfilter_mode to
// LZMA_SUBFILTER_NONE yet, because we
// haven't written the Unset Subfilter
// marker yet.
coder->subfilter.mode = SUB_END_MARKER;
coder->sequence = SEQ_FLUSH;
break;
}
// Return if we couldn't fill the buffer or
// if an error occurred.
if (coder->subblock.size < coder->subblock.limit
|| ret != LZMA_OK)
return ret;
}
coder->sequence = SEQ_FLUSH;
// SEQ_FILL doesn't produce any output so falling through
// to SEQ_FLUSH is safe.
assert(*out_pos < out_size);
// Fall through
case SEQ_FLUSH:
if (coder->options != NULL) {
// Update the alignment variable.
coder->alignment.multiple = coder->options->alignment;
if (coder->alignment.multiple
< LZMA_SUBBLOCK_ALIGNMENT_MIN
|| coder->alignment.multiple
> LZMA_SUBBLOCK_ALIGNMENT_MAX)
return LZMA_OPTIONS_ERROR;
// Run-length encoder
//
// First check if there is some data pending and we
// have an obvious need to flush it immediately.
if (coder->rle.count > 0
&& (coder->rle.size
!= coder->options->rle
|| coder->subblock.size
% coder->rle.size)) {
subblock_rle_flush(coder);
break;
}
// Grab the (possibly new) RLE chunk size and
// validate it.
coder->rle.size = coder->options->rle;
if (coder->rle.size > LZMA_SUBBLOCK_RLE_MAX)
return LZMA_OPTIONS_ERROR;
if (coder->subblock.size != 0
&& coder->rle.size
!= LZMA_SUBBLOCK_RLE_OFF
&& coder->subblock.size
% coder->rle.size == 0) {
// Initialize coder->rle.buffer if we don't
// have RLE already running.
if (coder->rle.count == 0)
memcpy(coder->rle.buffer,
coder->subblock.data,
coder->rle.size);
// Test if coder->subblock.data is repeating.
// If coder->rle.count would overflow, we
// force flushing. Forced flushing shouldn't
// really happen in real-world situations.
const size_t count = coder->subblock.size
/ coder->rle.size;
if (UINT64_MAX - count > coder->rle.count
&& is_repeating(
coder->rle.buffer,
coder->rle.size,
coder->subblock.data,
count)) {
coder->rle.count += count;
coder->rle.in_pending += coder
->subblock.in_pending;
coder->subblock.in_pending = 0;
coder->subblock.size = 0;
} else if (coder->rle.count > 0) {
// It's not repeating or at least not
// with the same byte sequence as the
// earlier Subblock Data buffers. We
// have some data pending in the RLE
// buffer already, so do a flush.
// Once flushed, we will check again
// if the Subblock Data happens to
// contain a different repeating
// sequence.
subblock_rle_flush(coder);
break;
}
}
}
// If we now have some data left in coder->subblock, the RLE
// buffer is empty and we must write a regular Subblock Data.
if (coder->subblock.size > 0) {
assert(coder->rle.count == 0);
coder->tmp = coder->subblock.size - 1;
coder->sequence = SEQ_DATA_SIZE_0;
break;
}
// Check if we should enable Subfilter.
if (coder->subfilter.mode == SUB_SET) {
if (coder->rle.count > 0)
subblock_rle_flush(coder);
else
coder->sequence = SEQ_SUBFILTER_INIT;
break;
}
// Check if we have just finished Subfiltering.
if (coder->subfilter.mode == SUB_END_MARKER) {
if (coder->rle.count > 0) {
subblock_rle_flush(coder);
break;
}
coder->options->subfilter_mode = LZMA_SUBFILTER_NONE;
coder->subfilter.mode = SUB_NONE;
write_byte(0x50);
if (*out_pos == out_size)
return LZMA_OK;
}
// Check if we have already written everything.
if (action != LZMA_RUN && *in_pos == in_size
&& (coder->subfilter.mode == SUB_NONE
|| coder->subfilter.mode == SUB_FLUSH)) {
if (coder->rle.count > 0) {
subblock_rle_flush(coder);
break;
}
if (action == LZMA_SYNC_FLUSH) {
if (coder->subfilter.mode == SUB_FLUSH)
coder->subfilter.mode = SUB_RUN;
coder->subfilter.mode_locked = false;
coder->sequence = SEQ_FILL;
} else {
assert(action == LZMA_FINISH);
// Write EOPM.
// NOTE: No need to use write_byte() here
// since we are finishing.
out[*out_pos] = 0x10;
++*out_pos;
}
return LZMA_STREAM_END;
}
// Otherwise we have more work to do.
coder->sequence = SEQ_FILL;
break;
case SEQ_RLE_COUNT_0:
assert(coder->rle.count > 0);
if (coder->rle.count == 1) {
// The buffer should be repeated only once. Fix
// the alignment and write the first byte of
// Subblock Type `Data'.
if (subblock_align(coder, out, out_pos, out_size,
coder->rle.size, ALIGN_SKEW_DATA))
return LZMA_OK;
write_byte(0x20 | (coder->tmp & 0x0F));
} else {
// We have something to actually repeat, which should
// mean that it takes less space with run-length
// encoding.
if (subblock_align(coder, out, out_pos, out_size,
coder->rle.size,
ALIGN_SKEW_REPEATING_DATA))
return LZMA_OK;
write_byte(0x30 | (coder->tmp & 0x0F));
}
// NOTE: If we have to write more than one Repeating Data
// due to rle.count > REPEAT_COUNT_MAX, the subsequent
// Repeating Data Subblocks may get wrong alignment, because
// we add rle.in_pending to alignment.in_pos at once instead
// of adding only as much as this particular Repeating Data
// consumed input data. Correct alignment is always restored
// after all the required Repeating Data Subblocks have been
// written. This problem occurs in such a weird cases that
// it's not worth fixing.
coder->alignment.out_pos += coder->rle.size;
coder->alignment.in_pos += coder->rle.in_pending;
coder->rle.in_pending = 0;
coder->sequence = SEQ_RLE_COUNT_1;
break;
case SEQ_RLE_COUNT_1:
write_byte(coder->tmp >> 4);
coder->sequence = SEQ_RLE_COUNT_2;
break;
case SEQ_RLE_COUNT_2:
write_byte(coder->tmp >> 12);
coder->sequence = SEQ_RLE_COUNT_3;
break;
case SEQ_RLE_COUNT_3:
write_byte(coder->tmp >> 20);
// Again, see if we are writing regular Data or Repeating Data.
// In the former case, we skip SEQ_RLE_SIZE.
if (coder->rle.count == 1)
coder->sequence = SEQ_RLE_DATA;
else
coder->sequence = SEQ_RLE_SIZE;
if (coder->rle.count > REPEAT_COUNT_MAX)
coder->rle.count -= REPEAT_COUNT_MAX;
else
coder->rle.count = 0;
break;
case SEQ_RLE_SIZE:
assert(coder->rle.size >= LZMA_SUBBLOCK_RLE_MIN);
assert(coder->rle.size <= LZMA_SUBBLOCK_RLE_MAX);
write_byte(coder->rle.size - 1);
coder->sequence = SEQ_RLE_DATA;
break;
case SEQ_RLE_DATA:
lzma_bufcpy(coder->rle.buffer, &coder->pos, coder->rle.size,
out, out_pos, out_size);
if (coder->pos < coder->rle.size)
return LZMA_OK;
coder->pos = 0;
coder->sequence = SEQ_FLUSH;
break;
case SEQ_DATA_SIZE_0:
// We need four bytes for the Size field.
if (subblock_align(coder, out, out_pos, out_size,
coder->subblock.size, ALIGN_SKEW_DATA))
return LZMA_OK;
coder->alignment.out_pos += coder->subblock.size;
coder->alignment.in_pos += coder->subblock.in_pending;
coder->subblock.in_pending = 0;
write_byte(0x20 | (coder->tmp & 0x0F));
coder->sequence = SEQ_DATA_SIZE_1;
break;
case SEQ_DATA_SIZE_1:
write_byte(coder->tmp >> 4);
coder->sequence = SEQ_DATA_SIZE_2;
break;
case SEQ_DATA_SIZE_2:
write_byte(coder->tmp >> 12);
coder->sequence = SEQ_DATA_SIZE_3;
break;
case SEQ_DATA_SIZE_3:
write_byte(coder->tmp >> 20);
coder->sequence = SEQ_DATA;
break;
case SEQ_DATA:
lzma_bufcpy(coder->subblock.data, &coder->pos,
coder->subblock.size, out, out_pos, out_size);
if (coder->pos < coder->subblock.size)
return LZMA_OK;
coder->subblock.size = 0;
coder->pos = 0;
coder->sequence = SEQ_FLUSH;
break;
case SEQ_SUBFILTER_INIT: {
assert(coder->subblock.size == 0);
assert(coder->subblock.in_pending == 0);
assert(coder->rle.count == 0);
assert(coder->rle.in_pending == 0);
assert(coder->subfilter.mode == SUB_SET);
assert(coder->options != NULL);
// There must be a filter specified.
if (coder->options->subfilter_options.id == LZMA_VLI_UNKNOWN)
return LZMA_OPTIONS_ERROR;
// Initialize a raw encoder to work as a Subfilter.
lzma_filter options[2];
options[0] = coder->options->subfilter_options;
options[1].id = LZMA_VLI_UNKNOWN;
return_if_error(lzma_raw_encoder_init(
&coder->subfilter.subcoder, allocator,
options));
// Encode the Filter Flags field into a buffer. This should
// never fail since we have already successfully initialized
// the Subfilter itself. Check it still, and return
// LZMA_PROG_ERROR instead of whatever the ret would say.
lzma_ret ret = lzma_filter_flags_size(
&coder->subfilter.flags_size, options);
assert(ret == LZMA_OK);
if (ret != LZMA_OK)
return LZMA_PROG_ERROR;
coder->subfilter.flags = lzma_alloc(
coder->subfilter.flags_size, allocator);
if (coder->subfilter.flags == NULL)
return LZMA_MEM_ERROR;
// Now we have a big-enough buffer. Encode the Filter Flags.
// Like above, this should never fail.
size_t dummy = 0;
ret = lzma_filter_flags_encode(options, coder->subfilter.flags,
&dummy, coder->subfilter.flags_size);
assert(ret == LZMA_OK);
assert(dummy == coder->subfilter.flags_size);
if (ret != LZMA_OK || dummy != coder->subfilter.flags_size)
return LZMA_PROG_ERROR;
// Write a Subblock indicating a new Subfilter.
write_byte(0x40);
coder->options->subfilter_mode = LZMA_SUBFILTER_RUN;
coder->subfilter.mode = SUB_RUN;
coder->alignment.out_pos += coder->subfilter.flags_size;
coder->sequence = SEQ_SUBFILTER_FLAGS;
// It is safe to fall through because SEQ_SUBFILTER_FLAGS
// uses lzma_bufcpy() which doesn't write unless there is
// output space.
}
// Fall through
case SEQ_SUBFILTER_FLAGS:
// Copy the Filter Flags to the output stream.
lzma_bufcpy(coder->subfilter.flags, &coder->pos,
coder->subfilter.flags_size,
out, out_pos, out_size);
if (coder->pos < coder->subfilter.flags_size)
return LZMA_OK;
lzma_free(coder->subfilter.flags, allocator);
coder->subfilter.flags = NULL;
coder->pos = 0;
coder->sequence = SEQ_FILL;
break;
default:
return LZMA_PROG_ERROR;
}
return LZMA_OK;
}
static lzma_ret
subblock_encode(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)
{
if (coder->next.code == NULL)
return subblock_buffer(coder, allocator, in, in_pos, in_size,
out, out_pos, out_size, action);
while (*out_pos < out_size
&& (*in_pos < in_size || action != LZMA_RUN)) {
if (!coder->next_finished
&& coder->temp.pos == coder->temp.size) {
coder->temp.pos = 0;
coder->temp.size = 0;
const lzma_ret ret = coder->next.code(coder->next.coder,
allocator, in, in_pos, in_size,
coder->temp.buffer, &coder->temp.size,
LZMA_BUFFER_SIZE, action);
if (ret == LZMA_STREAM_END) {
assert(action != LZMA_RUN);
coder->next_finished = true;
} else if (coder->temp.size == 0 || ret != LZMA_OK) {
return ret;
}
}
const lzma_ret ret = subblock_buffer(coder, allocator,
coder->temp.buffer, &coder->temp.pos,
coder->temp.size, out, out_pos, out_size,
coder->next_finished ? LZMA_FINISH : LZMA_RUN);
if (ret == LZMA_STREAM_END) {
assert(action != LZMA_RUN);
assert(coder->next_finished);
return LZMA_STREAM_END;
}
if (ret != LZMA_OK)
return ret;
}
return LZMA_OK;
}
static void
subblock_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
lzma_next_end(&coder->next, allocator);
lzma_next_end(&coder->subfilter.subcoder, allocator);
lzma_free(coder->subblock.data, allocator);
lzma_free(coder->subfilter.flags, allocator);
lzma_free(coder, allocator);
return;
}
extern lzma_ret
lzma_subblock_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
const lzma_filter_info *filters)
{
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
next->code = &subblock_encode;
next->end = &subblock_encoder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
next->coder->subblock.data = NULL;
next->coder->subblock.limit = 0;
next->coder->subfilter.subcoder = LZMA_NEXT_CODER_INIT;
} else {
lzma_next_end(&next->coder->subfilter.subcoder,
allocator);
lzma_free(next->coder->subfilter.flags, allocator);
}
next->coder->subfilter.flags = NULL;
next->coder->next_finished = false;
next->coder->sequence = SEQ_FILL;
next->coder->options = filters[0].options;
next->coder->pos = 0;
next->coder->alignment.in_pos = 0;
next->coder->alignment.out_pos = 0;
next->coder->subblock.size = 0;
next->coder->subblock.in_pending = 0;
next->coder->rle.count = 0;
next->coder->rle.in_pending = 0;
next->coder->subfilter.mode = SUB_NONE;
next->coder->subfilter.mode_locked = false;
next->coder->temp.pos = 0;
next->coder->temp.size = 0;
// Grab some values from the options structure if it is available.
size_t subblock_size_limit;
if (next->coder->options != NULL) {
if (next->coder->options->alignment
< LZMA_SUBBLOCK_ALIGNMENT_MIN
|| next->coder->options->alignment
> LZMA_SUBBLOCK_ALIGNMENT_MAX) {
subblock_encoder_end(next->coder, allocator);
return LZMA_OPTIONS_ERROR;
}
next->coder->alignment.multiple
= next->coder->options->alignment;
next->coder->subfilter.allow
= next->coder->options->allow_subfilters;
subblock_size_limit = next->coder->options->subblock_data_size;
} else {
next->coder->alignment.multiple
= LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
next->coder->subfilter.allow = false;
subblock_size_limit = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT;
}
return_if_error(subblock_data_size(next->coder, allocator,
subblock_size_limit));
return lzma_next_filter_init(
&next->coder->next, allocator, filters + 1);
}

View File

@ -1,21 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file subblock_encoder.h
/// \brief Encoder of the Subblock filter
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_SUBBLOCK_ENCODER_H
#define LZMA_SUBBLOCK_ENCODER_H
#include "common.h"
extern lzma_ret lzma_subblock_encoder_init(lzma_next_coder *next,
lzma_allocator *allocator, const lzma_filter_info *filters);
#endif

View File

@ -4,9 +4,9 @@
.\" This file has been put into the public domain.
.\" You can do whatever you want with this file.
.\"
.TH LZMAINFO 1 "2009-08-13" "Tukaani" "XZ Utils"
.TH LZMAINFO 1 "2010-09-27" "Tukaani" "XZ Utils"
.SH NAME
lzmainfo \- show infomation stored in the .lzma file header
lzmainfo \- show information stored in the .lzma file header
.SH SYNOPSIS
.B lzmainfo
.RB [ \-\-help ]
@ -16,10 +16,12 @@ lzmainfo \- show infomation stored in the .lzma file header
.B lzmainfo
shows information stored in the
.B .lzma
file header. It reads the first 13 bytes from the specified
file header.
It reads the first 13 bytes from the specified
.IR file ,
decodes the header, and prints it to standard output in human
readable format. If no
readable format.
If no
.I files
are given or
.I file
@ -27,16 +29,19 @@ is
.BR \- ,
standard input is read.
.PP
Usually the most interesting information is the uncompressed size and
the dictionary size. Uncompressed size can be shown only if the file is
in the non-streamed
Usually the most interesting information is
the uncompressed size and the dictionary size.
Uncompressed size can be shown only if
the file is in the non-streamed
.B .lzma
format variant. The amount of memory required to decompress the file is
format variant.
The amount of memory required to decompress the file is
a few dozen kilobytes plus the dictionary size.
.PP
.B lzmainfo
is included in XZ Utils primarily for backward compatibility with LZMA Utils.
.SH EXIT STATUS
is included in XZ Utils primarily for
backward compatibility with LZMA Utils.
.SH "EXIT STATUS"
.TP
.B 0
All is good.
@ -51,5 +56,5 @@ while the correct suffix would be
.B MiB
(2^20 bytes).
This is to keep the output compatible with LZMA Utils.
.SH SEE ALSO
.SH "SEE ALSO"
.BR xz (1)

View File

@ -20,6 +20,11 @@
#include "tuklib_progname.h"
#include "tuklib_exit.h"
#ifdef TUKLIB_DOSLIKE
# include <fcntl.h>
# include <io.h>
#endif
static void lzma_attribute((noreturn))
help(void)
@ -43,7 +48,7 @@ _("Usage: %s [--help] [--version] [FILE]...\n"
static void lzma_attribute((noreturn))
version(void)
{
puts("lzmainfo (" PACKAGE_NAME ") " PACKAGE_VERSION);
puts("lzmainfo (" PACKAGE_NAME ") " LZMA_VERSION_STRING);
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, true);
}
@ -150,7 +155,7 @@ lzmainfo(const char *name, FILE *f)
lzma_options_lzma *opt = filter.options;
printf("\nDictionary size: "
"%u MB (2^%u bytes)\n"
"%" PRIu32 " MB (2^%" PRIu32 " bytes)\n"
"Literal context bits (lc): %" PRIu32 "\n"
"Literal pos bits (lp): %" PRIu32 "\n"
"Number of pos bits (pb): %" PRIu32 "\n",
@ -171,6 +176,10 @@ main(int argc, char **argv)
parse_args(argc, argv);
#ifdef TUKLIB_DOSLIKE
setmode(fileno(stdin), O_BINARY);
#endif
int ret = EXIT_SUCCESS;
// We print empty lines around the output only when reading from

View File

@ -25,15 +25,40 @@ bool opt_robot = false;
// We don't modify or free() this, but we need to assign it in some
// non-const pointers.
const char *stdin_filename = "(stdin)";
const char stdin_filename[] = "(stdin)";
/// Parse and set the memory usage limit for compression and/or decompression.
static void
parse_memlimit(const char *name, const char *name_percentage, char *str,
bool set_compress, bool set_decompress)
{
bool is_percentage = false;
uint64_t value;
const size_t len = strlen(str);
if (len > 0 && str[len - 1] == '%') {
str[len - 1] = '\0';
is_percentage = true;
value = str_to_uint64(name_percentage, str, 1, 100);
} else {
// On 32-bit systems, SIZE_MAX would make more sense than
// UINT64_MAX. But use UINT64_MAX still so that scripts
// that assume > 4 GiB values don't break.
value = str_to_uint64(name, str, 0, UINT64_MAX);
}
hardware_memlimit_set(
value, set_compress, set_decompress, is_percentage);
return;
}
static void
parse_real(args_info *args, int argc, char **argv)
{
enum {
OPT_SUBBLOCK = INT_MIN,
OPT_X86,
OPT_X86 = INT_MIN,
OPT_POWERPC,
OPT_IA64,
OPT_ARM,
@ -46,6 +71,9 @@ parse_real(args_info *args, int argc, char **argv)
OPT_NO_SPARSE,
OPT_FILES,
OPT_FILES0,
OPT_MEM_COMPRESS,
OPT_MEM_DECOMPRESS,
OPT_NO_ADJUST,
OPT_INFO_MEMORY,
OPT_ROBOT,
};
@ -75,7 +103,11 @@ parse_real(args_info *args, int argc, char **argv)
// Basic compression settings
{ "format", required_argument, NULL, 'F' },
{ "check", required_argument, NULL, 'C' },
{ "memory", required_argument, NULL, 'M' },
{ "memlimit-compress", required_argument, NULL, OPT_MEM_COMPRESS },
{ "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS },
{ "memlimit", required_argument, NULL, 'M' },
{ "memory", required_argument, NULL, 'M' }, // Old alias
{ "no-adjust", no_argument, NULL, OPT_NO_ADJUST },
{ "threads", required_argument, NULL, 'T' },
{ "extreme", no_argument, NULL, 'e' },
@ -92,7 +124,6 @@ parse_real(args_info *args, int argc, char **argv)
{ "armthumb", optional_argument, NULL, OPT_ARMTHUMB },
{ "sparc", optional_argument, NULL, OPT_SPARC },
{ "delta", optional_argument, NULL, OPT_DELTA },
{ "subblock", optional_argument, NULL, OPT_SUBBLOCK },
// Other options
{ "quiet", no_argument, NULL, 'q' },
@ -104,7 +135,7 @@ parse_real(args_info *args, int argc, char **argv)
{ "long-help", no_argument, NULL, 'H' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
{ NULL, 0, NULL, 0 }
};
int c;
@ -118,28 +149,25 @@ parse_real(args_info *args, int argc, char **argv)
coder_set_preset(c - '0');
break;
// --memory
case 'M': {
// Support specifying the limit as a percentage of
// installed physical RAM.
size_t len = strlen(optarg);
if (len > 0 && optarg[len - 1] == '%') {
optarg[len - 1] = '\0';
hardware_memlimit_set_percentage(
str_to_uint64(
"memory%", optarg, 1, 100));
} else {
// On 32-bit systems, SIZE_MAX would make more
// sense than UINT64_MAX. But use UINT64_MAX
// still so that scripts that assume > 4 GiB
// values don't break.
hardware_memlimit_set(str_to_uint64(
"memory", optarg,
0, UINT64_MAX));
}
// --memlimit-compress
case OPT_MEM_COMPRESS:
parse_memlimit("memlimit-compress",
"memlimit-compress%", optarg,
true, false);
break;
// --memlimit-decompress
case OPT_MEM_DECOMPRESS:
parse_memlimit("memlimit-decompress",
"memlimit-decompress%", optarg,
false, true);
break;
// --memlimit
case 'M':
parse_memlimit("memlimit", "memlimit%", optarg,
true, true);
break;
}
// --suffix
case 'S':
@ -179,7 +207,7 @@ parse_real(args_info *args, int argc, char **argv)
// --info-memory
case OPT_INFO_MEMORY:
// This doesn't return.
message_memlimit();
hardware_memlimit_show();
// --help
case 'h':
@ -234,11 +262,6 @@ parse_real(args_info *args, int argc, char **argv)
// Filter setup
case OPT_SUBBLOCK:
coder_add_filter(LZMA_FILTER_SUBBLOCK,
options_subblock(optarg));
break;
case OPT_X86:
coder_add_filter(LZMA_FILTER_X86,
options_bcj(optarg));
@ -374,6 +397,10 @@ parse_real(args_info *args, int argc, char **argv)
break;
case OPT_NO_ADJUST:
opt_auto_adjust = false;
break;
default:
message_try_help();
tuklib_exit(E_ERROR, E_ERROR, false);
@ -385,9 +412,9 @@ parse_real(args_info *args, int argc, char **argv)
static void
parse_environment(args_info *args, char *argv0)
parse_environment(args_info *args, char *argv0, const char *varname)
{
char *env = getenv("XZ_OPT");
char *env = getenv(varname);
if (env == NULL)
return;
@ -413,10 +440,11 @@ parse_environment(args_info *args, char *argv0)
// Keep argc small enough to fit into a singed int
// and to keep it usable for memory allocation.
if (++argc == MIN(INT_MAX, SIZE_MAX / sizeof(char *)))
if (++argc == my_min(
INT_MAX, SIZE_MAX / sizeof(char *)))
message_fatal(_("The environment variable "
"XZ_OPT contains too many "
"arguments"));
"%s contains too many "
"arguments"), varname);
}
}
@ -504,8 +532,9 @@ args_parse(args_info *args, int argc, char **argv)
}
}
// First the flags from environment
parse_environment(args, argv[0]);
// First the flags from the environment
parse_environment(args, argv[0], "XZ_DEFAULTS");
parse_environment(args, argv[0], "XZ_OPT");
// Then from the command line
parse_real(args, argc, argv);

View File

@ -37,6 +37,6 @@ extern bool opt_keep_original;
// extern bool opt_recursive;
extern bool opt_robot;
extern const char *stdin_filename;
extern const char stdin_filename[];
extern void args_parse(args_info *args, int argc, char **argv);

View File

@ -22,8 +22,8 @@ enum coder_init_ret {
enum operation_mode opt_mode = MODE_COMPRESS;
enum format_type opt_format = FORMAT_AUTO;
bool opt_auto_adjust = true;
/// Stream used to communicate with liblzma
@ -42,14 +42,6 @@ static size_t filters_count = 0;
/// Number of the preset (0-9)
static size_t preset_number = 6;
/// True if we should auto-adjust the compression settings to use less memory
/// if memory usage limit is too low for the original settings.
static bool auto_adjust = true;
/// Indicate if no preset has been explicitly given. In that case, if we need
/// to auto-adjust for lower memory usage, we won't print a warning.
static bool preset_default = true;
/// If a preset is used (no custom filter chain) and preset_extreme is true,
/// a significantly slower compression is used to achieve slightly better
/// compression ratio.
@ -75,7 +67,15 @@ extern void
coder_set_preset(size_t new_preset)
{
preset_number = new_preset;
preset_default = false;
// Setting a preset makes us forget a possibly defined custom
// filter chain.
while (filters_count > 0) {
--filters_count;
free(filters[filters_count].options);
filters[filters_count].options = NULL;
}
return;
}
@ -145,8 +145,6 @@ coder_set_compression_settings(void)
? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2;
filters[0].options = &opt_lzma;
filters_count = 1;
} else {
preset_default = false;
}
// Terminate the filter options array.
@ -168,12 +166,12 @@ coder_set_compression_settings(void)
"with the .xz format"));
// Print the selected filter chain.
message_filters(V_DEBUG, filters);
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.
const uint64_t memory_limit = hardware_memlimit_get();
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);
@ -186,12 +184,19 @@ coder_set_compression_settings(void)
// Print memory usage info before possible dictionary
// size auto-adjusting.
message_mem_needed(V_DEBUG, memory_usage);
if (opt_mode == MODE_COMPRESS) {
const uint64_t decmem = lzma_raw_decoder_memusage(filters);
if (decmem != UINT64_MAX)
message(V_DEBUG, _("Decompression will need "
"%s MiB of memory."), uint64_to_str(
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 (!auto_adjust || opt_format == FORMAT_RAW)
if (!opt_auto_adjust || opt_format == FORMAT_RAW)
memlimit_too_small(memory_usage);
assert(opt_mode == MODE_COMPRESS);
@ -239,18 +244,15 @@ coder_set_compression_settings(void)
}
// Tell the user that we decreased the dictionary size.
// However, omit the message if no preset or custom chain
// was given. FIXME: Always warn?
if (!preset_default)
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));
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));
}
/*
@ -410,12 +412,14 @@ coder_init(file_pair *pair)
case FORMAT_XZ:
ret = lzma_stream_decoder(&strm,
hardware_memlimit_get(), flags);
hardware_memlimit_get(
MODE_DECOMPRESS), flags);
break;
case FORMAT_LZMA:
ret = lzma_alone_decoder(&strm,
hardware_memlimit_get());
hardware_memlimit_get(
MODE_DECOMPRESS));
break;
case FORMAT_RAW:

View File

@ -37,6 +37,10 @@ extern enum operation_mode opt_mode;
/// This is set in args.c.
extern enum format_type opt_format;
/// If true, the compression settings are automatically adjusted down if
/// they exceed the memory usage limit.
extern bool opt_auto_adjust;
/// Set the integrity check type used when compressing
extern void coder_set_check(lzma_check check);

View File

@ -370,15 +370,16 @@ io_open_src_real(file_pair *pair)
}
#ifdef O_NOFOLLOW
// Give an understandable error message in if reason
// Give an understandable error message if the reason
// for failing was that the file was a symbolic link.
//
// Note that at least Linux, OpenBSD, Solaris, and Darwin
// use ELOOP to indicate if O_NOFOLLOW was the reason
// use ELOOP to indicate that O_NOFOLLOW was the reason
// that open() failed. Because there may be
// directories in the pathname, ELOOP may occur also
// because of a symlink loop in the directory part.
// So ELOOP doesn't tell us what actually went wrong.
// So ELOOP doesn't tell us what actually went wrong,
// and this stupidity went into POSIX-1.2008 too.
//
// FreeBSD associates EMLINK with O_NOFOLLOW and
// Tru64 uses ENOTSUP. We use these directly here
@ -396,10 +397,10 @@ io_open_src_real(file_pair *pair)
was_symlink = true;
# elif defined(__NetBSD__)
// FIXME? As of 2008-11-20, NetBSD doesn't document what
// errno is used with O_NOFOLLOW. It seems to be EFTYPE,
// but since it isn't documented, it may be wrong to rely
// on it here.
// As of 2010-09-05, NetBSD doesn't document what errno is
// used with O_NOFOLLOW. It is EFTYPE though, and I
// understood that is very unlikely to change even though
// it is undocumented.
if (errno == EFTYPE)
was_symlink = true;

View File

@ -18,8 +18,11 @@
/// the --threads=NUM command line option.
static uint32_t threadlimit;
/// Memory usage limit
static uint64_t memlimit;
/// Memory usage limit for compression
static uint64_t memlimit_compress;
/// Memory usage limit for decompression
static uint64_t memlimit_decompress;
/// Total amount of physical RAM
static uint64_t total_ram;
@ -49,50 +52,79 @@ hardware_threadlimit_get(void)
extern void
hardware_memlimit_set(uint64_t new_memlimit)
hardware_memlimit_set(uint64_t new_memlimit,
bool set_compress, bool set_decompress, bool is_percentage)
{
if (new_memlimit != 0) {
memlimit = new_memlimit;
} else {
// The default depends on the amount of RAM but so that
// on "low-memory" systems the relative limit is higher
// to make it more likely that files created with "xz -9"
// will still decompress without overriding the limit
// manually.
//
// If 40 % of RAM is 80 MiB or more, use 40 % of RAM as
// the limit.
memlimit = 40 * total_ram / 100;
if (memlimit < UINT64_C(80) * 1024 * 1024) {
// If 80 % of RAM is less than 80 MiB,
// use 80 % of RAM as the limit.
memlimit = 80 * total_ram / 100;
if (memlimit > UINT64_C(80) * 1024 * 1024) {
// Otherwise use 80 MiB as the limit.
memlimit = UINT64_C(80) * 1024 * 1024;
}
}
if (is_percentage) {
assert(new_memlimit > 0);
assert(new_memlimit <= 100);
new_memlimit = (uint32_t)new_memlimit * total_ram / 100;
}
if (set_compress)
memlimit_compress = new_memlimit;
if (set_decompress)
memlimit_decompress = new_memlimit;
return;
}
extern uint64_t
hardware_memlimit_get(enum operation_mode mode)
{
// Zero is a special value that indicates the default. Currently
// the default simply disables the limit. Once there is threading
// support, this might be a little more complex, because there will
// probably be a special case where a user asks for "optimal" number
// of threads instead of a specific number (this might even become
// the default mode). Each thread may use a significant amount of
// memory. When there are no memory usage limits set, we need some
// default soft limit for calculating the "optimal" number of
// threads.
const uint64_t memlimit = mode == MODE_COMPRESS
? memlimit_compress : memlimit_decompress;
return memlimit != 0 ? memlimit : UINT64_MAX;
}
/// Helper for hardware_memlimit_show() to print one human-readable info line.
static void
memlimit_show(const char *str, uint64_t value)
{
// The memory usage limit is considered to be disabled if value
// is 0 or UINT64_MAX. This might get a bit more complex once there
// is threading support. See the comment in hardware_memlimit_get().
if (value == 0 || value == UINT64_MAX)
printf("%s %s\n", str, _("Disabled"));
else
printf("%s %s MiB (%s B)\n", str,
uint64_to_str(round_up_to_mib(value), 0),
uint64_to_str(value, 1));
return;
}
extern void
hardware_memlimit_set_percentage(uint32_t percentage)
hardware_memlimit_show(void)
{
assert(percentage > 0);
assert(percentage <= 100);
if (opt_robot) {
printf("%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n", total_ram,
memlimit_compress, memlimit_decompress);
} else {
// TRANSLATORS: Test with "xz --info-memory" to see if
// the alignment looks nice.
memlimit_show(_("Total amount of physical memory (RAM): "),
total_ram);
memlimit_show(_("Memory usage limit for compression: "),
memlimit_compress);
memlimit_show(_("Memory usage limit for decompression: "),
memlimit_decompress);
}
memlimit = percentage * total_ram / 100;
return;
}
extern uint64_t
hardware_memlimit_get(void)
{
return memlimit;
tuklib_exit(E_SUCCESS, E_ERROR, message_verbosity_get() != V_SILENT);
}
@ -106,7 +138,7 @@ hardware_init(void)
total_ram = (uint64_t)(ASSUME_RAM) * 1024 * 1024;
// Set the defaults.
hardware_memlimit_set(0);
hardware_memlimit_set(0, true, true, false);
hardware_threadlimit_set(0);
return;
}

View File

@ -23,13 +23,16 @@ extern void hardware_threadlimit_set(uint32_t threadlimit);
extern uint32_t hardware_threadlimit_get(void);
/// Set custom memory usage limit. This is used for both encoding and
/// decoding. Zero indicates resetting the limit back to defaults.
extern void hardware_memlimit_set(uint64_t memlimit);
/// Set the memory usage limit. There are separate limits for compression
/// and decompression (the latter includes also --list), one or both can
/// be set with a single call to this function. Zero indicates resetting
/// the limit back to the defaults. The limit can also be set as a percentage
/// of installed RAM; the percentage must be in the range [1, 100].
extern void hardware_memlimit_set(uint64_t new_memlimit,
bool set_compress, bool set_decompress, bool is_percentage);
/// Set custom memory usage limit as a percentage of installed RAM.
/// The percentage must be in the range [1, 100].
extern void hardware_memlimit_set_percentage(uint32_t percentage);
/// Get the current memory usage limit for compression or decompression.
extern uint64_t hardware_memlimit_get(enum operation_mode mode);
/// Get the current memory usage limit.
extern uint64_t hardware_memlimit_get(void);
/// Display the amount of RAM and memory usage limits and exit.
extern void hardware_memlimit_show(void) lzma_attribute((noreturn));

File diff suppressed because it is too large Load Diff

View File

@ -13,10 +13,15 @@
#include "private.h"
#include <ctype.h>
/// Exit status to use. This can be changed with set_exit_status().
static enum exit_status_type exit_status = E_SUCCESS;
#if defined(_WIN32) && !defined(__CYGWIN__)
/// exit_status has to be protected with a critical section due to
/// how "signal handling" is done on Windows. See signals.c for details.
static CRITICAL_SECTION exit_status_cs;
#endif
/// True if --no-warn is specified. When this is true, we don't set
/// the exit status to E_WARNING when something worth a warning happens.
static bool no_warn = false;
@ -27,9 +32,17 @@ set_exit_status(enum exit_status_type new_status)
{
assert(new_status == E_WARNING || new_status == E_ERROR);
#if defined(_WIN32) && !defined(__CYGWIN__)
EnterCriticalSection(&exit_status_cs);
#endif
if (exit_status != E_ERROR)
exit_status = new_status;
#if defined(_WIN32) && !defined(__CYGWIN__)
LeaveCriticalSection(&exit_status_cs);
#endif
return;
}
@ -129,6 +142,10 @@ read_name(const args_info *args)
int
main(int argc, char **argv)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
InitializeCriticalSection(&exit_status_cs);
#endif
// Set up the progname variable.
tuklib_progname_init(argv);
@ -262,11 +279,24 @@ main(int argc, char **argv)
// of calling tuklib_exit().
signals_exit();
// Make a local copy of exit_status to keep the Windows code
// thread safe. At this point it is fine if we miss the user
// pressing C-c and don't set the exit_status to E_ERROR on
// Windows.
#if defined(_WIN32) && !defined(__CYGWIN__)
EnterCriticalSection(&exit_status_cs);
#endif
enum exit_status_type es = exit_status;
#if defined(_WIN32) && !defined(__CYGWIN__)
LeaveCriticalSection(&exit_status_cs);
#endif
// Suppress the exit status indicating a warning if --no-warn
// was specified.
if (exit_status == E_WARNING && no_warn)
exit_status = E_SUCCESS;
if (es == E_WARNING && no_warn)
es = E_SUCCESS;
tuklib_exit(exit_status, E_ERROR,
message_verbosity_get() != V_SILENT);
tuklib_exit(es, E_ERROR, message_verbosity_get() != V_SILENT);
}

View File

@ -142,19 +142,19 @@ message_init(void)
*/
#ifdef SIGALRM
// At least DJGPP lacks SA_RESTART. It's not essential for us (the
// rest of the code can handle interrupted system calls), so just
// define it zero.
# ifndef SA_RESTART
// DJGPP lacks SA_RESTART, but it shouldn't give EINTR
// in most places either.
# if defined(__DJGPP__) && !defined(SA_RESTART)
# define SA_RESTART 0
# endif
// Establish the signal handlers which set a flag to tell us that
// progress info should be updated. Since these signals don't
// require any quick action, we set SA_RESTART.
// require any quick action, we set SA_RESTART. That way we don't
// need to block them either in signals_block() to keep stdio
// functions from getting EINTR.
static const int sigs[] = {
#ifdef SIGALRM
SIGALRM,
#endif
#ifdef SIGINFO
SIGINFO,
#endif
@ -321,7 +321,8 @@ progress_percentage(uint64_t in_pos)
double percentage = (double)(in_pos) / (double)(expected_in_size)
* 99.9;
static char buf[sizeof("99.9 %")];
// Use big enough buffer to hold e.g. a multibyte decimal point.
static char buf[16];
snprintf(buf, sizeof(buf), "%.1f %%", percentage);
return buf;
@ -333,12 +334,8 @@ progress_percentage(uint64_t in_pos)
static const char *
progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
{
// This is enough to hold sizes up to about 99 TiB if thousand
// separator is used, or about 1 PiB without thousand separator.
// After that the progress indicator will look a bit silly, since
// the compression ratio no longer fits with three decimal places.
static char buf[36];
// Use big enough buffer to hold e.g. a multibyte thousand separators.
static char buf[128];
char *pos = buf;
size_t left = sizeof(buf);
@ -402,7 +399,8 @@ progress_speed(uint64_t uncompressed_pos, uint64_t elapsed)
// - 9.9 KiB/s
// - 99 KiB/s
// - 999 KiB/s
static char buf[sizeof("999 GiB/s")];
// Use big enough buffer to hold e.g. a multibyte decimal point.
static char buf[16];
snprintf(buf, sizeof(buf), "%.*f %s",
speed > 9.9 ? 0 : 1, speed, unit[unit_index]);
return buf;
@ -588,12 +586,19 @@ message_progress_update(void)
// Print the actual progress message. The idea is that there is at
// least three spaces between the fields in typical situations, but
// even in rare situations there is at least one space.
fprintf(stderr, "\r %6s %35s %9s %10s %10s\r",
const char *cols[5] = {
progress_percentage(in_pos),
progress_sizes(compressed_pos, uncompressed_pos, false),
progress_speed(uncompressed_pos, elapsed),
progress_time(elapsed),
progress_remaining(in_pos, elapsed));
progress_remaining(in_pos, elapsed),
};
fprintf(stderr, "\r %*s %*s %*s %10s %10s\r",
tuklib_mbstr_fw(cols[0], 6), cols[0],
tuklib_mbstr_fw(cols[1], 35), cols[1],
tuklib_mbstr_fw(cols[2], 9), cols[2],
cols[3],
cols[4]);
#ifdef SIGALRM
// Updating the progress info was finished. Reset
@ -663,12 +668,19 @@ progress_flush(bool finished)
// statistics are printed in the same format as the progress
// indicator itself.
if (progress_automatic) {
fprintf(stderr, "\r %6s %35s %9s %10s %10s\n",
const char *cols[5] = {
finished ? "100 %" : progress_percentage(in_pos),
progress_sizes(compressed_pos, uncompressed_pos, true),
progress_speed(uncompressed_pos, elapsed),
progress_time(elapsed),
finished ? "" : progress_remaining(in_pos, elapsed));
finished ? "" : progress_remaining(in_pos, elapsed),
};
fprintf(stderr, "\r %*s %*s %*s %10s %10s\n",
tuklib_mbstr_fw(cols[0], 6), cols[0],
tuklib_mbstr_fw(cols[1], 35), cols[1],
tuklib_mbstr_fw(cols[2], 9), cols[2],
cols[3],
cols[4]);
} else {
// The filename is always printed.
fprintf(stderr, "%s: ", filename);
@ -848,13 +860,15 @@ message_mem_needed(enum message_verbosity v, uint64_t memusage)
// the user might need to +1 MiB to get high enough limit.)
memusage = round_up_to_mib(memusage);
// With US-ASCII:
// 2^64 with thousand separators + " MiB" suffix + '\0' = 26 + 4 + 1
char memlimitstr[32];
// But there may be multibyte chars so reserve enough space.
char memlimitstr[128];
// Show the memory usage limit as MiB unless it is less than 1 MiB.
// This way it's easy to notice errors where one has typed
// --memory=123 instead of --memory=123MiB.
uint64_t memlimit = hardware_memlimit_get();
uint64_t memlimit = hardware_memlimit_get(opt_mode);
if (memlimit < (UINT32_C(1) << 20)) {
snprintf(memlimitstr, sizeof(memlimitstr), "%s B",
uint64_to_str(memlimit, 1));
@ -876,114 +890,167 @@ message_mem_needed(enum message_verbosity v, uint64_t memusage)
}
extern void
message_filters(enum message_verbosity v, const lzma_filter *filters)
/// \brief Convert uint32_t to a nice string for --lzma[12]=dict=SIZE
///
/// The idea is to use KiB or MiB suffix when possible.
static const char *
uint32_to_optstr(uint32_t num)
{
if (v > verbosity)
return;
static char buf[16];
fprintf(stderr, _("%s: Filter chain:"), progname);
if ((num & ((UINT32_C(1) << 20) - 1)) == 0)
snprintf(buf, sizeof(buf), "%" PRIu32 "MiB", num >> 20);
else if ((num & ((UINT32_C(1) << 10) - 1)) == 0)
snprintf(buf, sizeof(buf), "%" PRIu32 "KiB", num >> 10);
else
snprintf(buf, sizeof(buf), "%" PRIu32, num);
return buf;
}
extern void
message_filters_to_str(char buf[FILTERS_STR_SIZE],
const lzma_filter *filters, bool all_known)
{
char *pos = buf;
size_t left = FILTERS_STR_SIZE;
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
fprintf(stderr, " --");
// Add the dashes for the filter option. A space is
// needed after the first and later filters.
my_snprintf(&pos, &left, "%s", i == 0 ? "--" : " --");
switch (filters[i].id) {
case LZMA_FILTER_LZMA1:
case LZMA_FILTER_LZMA2: {
const lzma_options_lzma *opt = filters[i].options;
const char *mode;
const char *mf;
const char *mode = NULL;
const char *mf = NULL;
switch (opt->mode) {
case LZMA_MODE_FAST:
mode = "fast";
break;
if (all_known) {
switch (opt->mode) {
case LZMA_MODE_FAST:
mode = "fast";
break;
case LZMA_MODE_NORMAL:
mode = "normal";
break;
case LZMA_MODE_NORMAL:
mode = "normal";
break;
default:
mode = "UNKNOWN";
break;
default:
mode = "UNKNOWN";
break;
}
switch (opt->mf) {
case LZMA_MF_HC3:
mf = "hc3";
break;
case LZMA_MF_HC4:
mf = "hc4";
break;
case LZMA_MF_BT2:
mf = "bt2";
break;
case LZMA_MF_BT3:
mf = "bt3";
break;
case LZMA_MF_BT4:
mf = "bt4";
break;
default:
mf = "UNKNOWN";
break;
}
}
switch (opt->mf) {
case LZMA_MF_HC3:
mf = "hc3";
break;
// Add the filter name and dictionary size, which
// is always known.
my_snprintf(&pos, &left, "lzma%c=dict=%s",
filters[i].id == LZMA_FILTER_LZMA2
? '2' : '1',
uint32_to_optstr(opt->dict_size));
case LZMA_MF_HC4:
mf = "hc4";
break;
// With LZMA1 also lc/lp/pb are known when
// decompressing, but this function is never
// used to print information about .lzma headers.
assert(filters[i].id == LZMA_FILTER_LZMA2
|| all_known);
case LZMA_MF_BT2:
mf = "bt2";
break;
case LZMA_MF_BT3:
mf = "bt3";
break;
case LZMA_MF_BT4:
mf = "bt4";
break;
default:
mf = "UNKNOWN";
break;
}
fprintf(stderr, "lzma%c=dict=%" PRIu32
// Print the rest of the options, which are known
// only when compressing.
if (all_known)
my_snprintf(&pos, &left,
",lc=%" PRIu32 ",lp=%" PRIu32
",pb=%" PRIu32
",mode=%s,nice=%" PRIu32 ",mf=%s"
",depth=%" PRIu32,
filters[i].id == LZMA_FILTER_LZMA2
? '2' : '1',
opt->dict_size,
opt->lc, opt->lp, opt->pb,
mode, opt->nice_len, mf, opt->depth);
break;
}
case LZMA_FILTER_X86:
fprintf(stderr, "x86");
break;
case LZMA_FILTER_POWERPC:
fprintf(stderr, "powerpc");
break;
case LZMA_FILTER_IA64:
fprintf(stderr, "ia64");
break;
case LZMA_FILTER_ARM:
fprintf(stderr, "arm");
break;
case LZMA_FILTER_ARMTHUMB:
fprintf(stderr, "armthumb");
break;
case LZMA_FILTER_SPARC: {
static const char bcj_names[][9] = {
"x86",
"powerpc",
"ia64",
"arm",
"armthumb",
"sparc",
};
const lzma_options_bcj *opt = filters[i].options;
my_snprintf(&pos, &left, "%s", bcj_names[filters[i].id
- LZMA_FILTER_X86]);
// Show the start offset only when really needed.
if (opt != NULL && opt->start_offset != 0)
my_snprintf(&pos, &left, "=start=%" PRIu32,
opt->start_offset);
case LZMA_FILTER_SPARC:
fprintf(stderr, "sparc");
break;
}
case LZMA_FILTER_DELTA: {
const lzma_options_delta *opt = filters[i].options;
fprintf(stderr, "delta=dist=%" PRIu32, opt->dist);
my_snprintf(&pos, &left, "delta=dist=%" PRIu32,
opt->dist);
break;
}
default:
fprintf(stderr, "UNKNOWN");
// This should be possible only if liblzma is
// newer than the xz tool.
my_snprintf(&pos, &left, "UNKNOWN");
break;
}
}
fputc('\n', stderr);
return;
}
extern void
message_filters_show(enum message_verbosity v, const lzma_filter *filters)
{
if (v > verbosity)
return;
char buf[FILTERS_STR_SIZE];
message_filters_to_str(buf, filters, true);
fprintf(stderr, _("%s: Filter chain: %s\n"), progname, buf);
return;
}
@ -999,28 +1066,13 @@ message_try_help(void)
}
extern void
message_memlimit(void)
{
if (opt_robot)
printf("%" PRIu64 "\n", hardware_memlimit_get());
else
printf(_("%s MiB (%s bytes)\n"),
uint64_to_str(
round_up_to_mib(hardware_memlimit_get()), 0),
uint64_to_str(hardware_memlimit_get(), 1));
tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
}
extern void
message_version(void)
{
// It is possible that liblzma version is different than the command
// line tool version, so print both.
if (opt_robot) {
printf("XZ_VERSION=%d\nLIBLZMA_VERSION=%d\n",
printf("XZ_VERSION=%" PRIu32 "\nLIBLZMA_VERSION=%" PRIu32 "\n",
LZMA_VERSION, lzma_version_number());
} else {
printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
@ -1038,8 +1090,11 @@ message_help(bool long_help)
"Compress or decompress FILEs in the .xz format.\n\n"),
progname);
puts(_("Mandatory arguments to long options are mandatory for "
"short options too.\n"));
// NOTE: The short help doesn't currently have options that
// take arguments.
if (long_help)
puts(_("Mandatory arguments to long options are mandatory "
"for short options too.\n"));
if (long_help)
puts(_(" Operation mode:\n"));
@ -1048,7 +1103,7 @@ message_help(bool long_help)
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
" -t, --test test compressed file integrity\n"
" -l, --list list information about files"));
" -l, --list list information about .xz files"));
if (long_help)
puts(_("\n Operation modifiers:\n"));
@ -1062,32 +1117,40 @@ message_help(bool long_help)
puts(_(
" --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"
" --files[=FILE] read filenames to process from FILE; if FILE is\n"
" omitted, filenames are read from the standard input;\n"
" filenames must be terminated with the newline character\n"
" --files0=[FILE] like --files but use the null character as terminator"));
" --files0[=FILE] like --files but use the null character as terminator"));
if (long_help) {
puts(_("\n Basic file format and compression options:\n"));
puts(_(
" -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: `crc32', `crc64' (default),\n"
" `sha256', or `none' (use with caution)"));
" -C, --check=CHECK integrity check type: `none' (use with caution),\n"
" `crc32', `crc64' (default), or `sha256'"));
}
puts(_(
" -0 .. -9 compression preset; 0-2 fast compression, 3-5 good\n"
" compression, 6-9 excellent compression; default is 6"));
" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
" decompressor memory usage into account before using 7-9!"));
puts(_(
" -e, --extreme use more CPU time when encoding to increase compression\n"
" ratio without increasing memory usage of the decoder"));
" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" does not affect decompressor memory requirements"));
if (long_help)
if (long_help) {
puts(_( // xgettext:no-c-format
" -M, --memory=NUM use roughly NUM bytes of memory at maximum; 0 indicates\n"
" the default setting, which is 40 % of total RAM"));
" --memlimit-compress=LIMIT\n"
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
" set memory usage limit for compression, decompression,\n"
" or both; LIMIT is in bytes, % of RAM, or 0 for defaults"));
puts(_(
" --no-adjust if compression settings exceed the memory usage limit,\n"
" give an error instead of adjusting the settings downwards"));
}
if (long_help) {
puts(_(
@ -1095,11 +1158,15 @@ message_help(bool long_help)
#if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) \
|| defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
// TRANSLATORS: The word "literal" in "literal context bits"
// means how many "context bits" to use when encoding
// literals. A literal is a single 8-bit byte. It doesn't
// mean "literally" here.
puts(_(
"\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=NUM reset options to preset number NUM (0-9)\n"
" preset=PRE reset options to a preset (0-9[e])\n"
" dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n"
" lc=NUM number of literal context bits (0-4; 3)\n"
" lp=NUM number of literal position bits (0-4; 0)\n"
@ -1112,9 +1179,9 @@ message_help(bool long_help)
puts(_(
"\n"
" --x86[=OPTS] x86 BCJ filter\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
" --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n"
" --ia64[=OPTS] IA64 (Itanium) BCJ filter\n"
" --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n"
" --arm[=OPTS] ARM BCJ filter (little endian only)\n"
" --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n"
" --sparc[=OPTS] SPARC BCJ filter\n"
@ -1127,15 +1194,6 @@ message_help(bool long_help)
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
" dist=NUM distance between bytes being subtracted\n"
" from each other (1-256; 1)"));
#endif
#if defined(HAVE_ENCODER_SUBBLOCK) || defined(HAVE_DECODER_SUBBLOCK)
puts(_(
"\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)"));
#endif
}
@ -1153,7 +1211,8 @@ message_help(bool long_help)
" --robot use machine-parsable messages (useful for scripts)"));
puts("");
puts(_(
" --info-memory display the memory usage limit and exit"));
" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"));
puts(_(
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"));
@ -1168,15 +1227,6 @@ message_help(bool long_help)
puts(_("\nWith no FILE, or when FILE is -, read standard input.\n"));
if (long_help) {
printf(_(
"On this system and configuration, this program will use a maximum of roughly\n"
"%s MiB RAM and "), uint64_to_str(round_up_to_mib(hardware_memlimit_get()), 0));
printf(N_("one thread.\n\n", "%s threads.\n\n",
hardware_threadlimit_get()),
uint64_to_str(hardware_threadlimit_get(), 0));
}
// 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

View File

@ -86,8 +86,24 @@ extern const char *message_strm(lzma_ret code);
extern void message_mem_needed(enum message_verbosity v, uint64_t memusage);
/// Buffer size for message_filters_to_str()
#define FILTERS_STR_SIZE 512
/// \brief Get the filter chain as a string
///
/// \param buf Pointer to caller allocated buffer to hold
/// the filter chain string
/// \param filters Pointer to the filter chain
/// \param all_known If true, all filter options are printed.
/// If false, only the options that get stored
/// into .xz headers are printed.
extern void message_filters_to_str(char buf[FILTERS_STR_SIZE],
const lzma_filter *filters, bool all_known);
/// Print the filter chain.
extern void message_filters(
extern void message_filters_show(
enum message_verbosity v, const lzma_filter *filters);
@ -95,10 +111,6 @@ extern void message_filters(
extern void message_try_help(void);
/// Print the memory usage limit and exit.
extern void message_memlimit(void) lzma_attribute((noreturn));
/// Prints the version number to stdout and exits with exit status SUCCESS.
extern void message_version(void) lzma_attribute((noreturn));

View File

@ -139,67 +139,6 @@ parse_options(const char *str, const option_map *opts,
}
//////////////
// Subblock //
//////////////
enum {
OPT_SIZE,
OPT_RLE,
OPT_ALIGN,
};
static void
set_subblock(void *options, uint32_t key, uint64_t value,
const char *valuestr lzma_attribute((unused)))
{
lzma_options_subblock *opt = options;
switch (key) {
case OPT_SIZE:
opt->subblock_data_size = value;
break;
case OPT_RLE:
opt->rle = value;
break;
case OPT_ALIGN:
opt->alignment = value;
break;
}
}
extern lzma_options_subblock *
options_subblock(const char *str)
{
static const option_map opts[] = {
{ "size", NULL, LZMA_SUBBLOCK_DATA_SIZE_MIN,
LZMA_SUBBLOCK_DATA_SIZE_MAX },
{ "rle", NULL, LZMA_SUBBLOCK_RLE_OFF,
LZMA_SUBBLOCK_RLE_MAX },
{ "align",NULL, LZMA_SUBBLOCK_ALIGNMENT_MIN,
LZMA_SUBBLOCK_ALIGNMENT_MAX },
{ NULL, NULL, 0, 0 }
};
lzma_options_subblock *options
= xmalloc(sizeof(lzma_options_subblock));
*options = (lzma_options_subblock){
.allow_subfilters = false,
.alignment = LZMA_SUBBLOCK_ALIGNMENT_DEFAULT,
.subblock_data_size = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT,
.rle = LZMA_SUBBLOCK_RLE_OFF,
};
parse_options(str, opts, &set_subblock, options);
return options;
}
///////////
// Delta //
///////////
@ -407,24 +346,13 @@ options_lzma(const char *str)
};
lzma_options_lzma *options = xmalloc(sizeof(lzma_options_lzma));
*options = (lzma_options_lzma){
.dict_size = LZMA_DICT_SIZE_DEFAULT,
.preset_dict = NULL,
.preset_dict_size = 0,
.lc = LZMA_LC_DEFAULT,
.lp = LZMA_LP_DEFAULT,
.pb = LZMA_PB_DEFAULT,
.mode = LZMA_MODE_NORMAL,
.nice_len = 64,
.mf = LZMA_MF_BT4,
.depth = 0,
};
if (lzma_lzma_preset(options, LZMA_PRESET_DEFAULT))
message_bug();
parse_options(str, opts, &set_lzma, options);
if (options->lc + options->lp > LZMA_LCLP_MAX)
message_fatal(_("The sum of lc and lp must be at "
"maximum of 4"));
message_fatal(_("The sum of lc and lp must not exceed 4"));
const uint32_t nice_len_min = options->mf & 0x0F;
if (options->nice_len < nice_len_min)

View File

@ -10,13 +10,6 @@
//
///////////////////////////////////////////////////////////////////////////////
/// \brief Parser for Subblock options
///
/// \return Pointer to allocated options structure.
/// Doesn't return on error.
extern lzma_options_subblock *options_subblock(const char *str);
/// \brief Parser for Delta options
///
/// \return Pointer to allocated options structure.

View File

@ -25,6 +25,12 @@
#include "tuklib_gettext.h"
#include "tuklib_progname.h"
#include "tuklib_exit.h"
#include "tuklib_mbstr.h"
#if defined(_WIN32) && !defined(__CYGWIN__)
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#ifndef STDIN_FILENO
# define STDIN_FILENO (fileno(stdin))

View File

@ -16,7 +16,7 @@
volatile sig_atomic_t user_abort = false;
#ifndef _WIN32
#if !(defined(_WIN32) && !defined(__CYGWIN__))
/// If we were interrupted by a signal, we store the signal number so that
/// we can raise that signal to kill the program when all cleanups have
@ -142,12 +142,19 @@ signals_exit(void)
const int sig = exit_signal;
if (sig != 0) {
#ifdef TUKLIB_DOSLIKE
// Don't raise(), set only exit status. This avoids
// printing unwanted message about SIGINT when the user
// presses C-c.
set_exit_status(E_ERROR);
#else
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sigfillset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(sig, &sa, NULL);
raise(exit_signal);
#endif
}
return;
@ -156,11 +163,14 @@ signals_exit(void)
#else
// While Windows has some very basic signal handling functions as required
// by C89, they are not really used, or so I understood. Instead, we use
// SetConsoleCtrlHandler() to catch user pressing C-c.
#include <windows.h>
// by C89, they are not really used, and e.g. SIGINT doesn't work exactly
// the way it does on POSIX (Windows creates a new thread for the signal
// handler). Instead, we use SetConsoleCtrlHandler() to catch user
// pressing C-c, because that seems to be the recommended way to do it.
//
// NOTE: This doesn't work under MSYS. Trying with SIGINT doesn't work
// either even if it appeared to work at first. So test using Windows
// console window.
static BOOL WINAPI
signal_handler(DWORD type lzma_attribute((unused)))
@ -168,9 +178,6 @@ signal_handler(DWORD type lzma_attribute((unused)))
// Since we don't get a signal number which we could raise() at
// signals_exit() like on POSIX, just set the exit status to
// indicate an error, so that we cannot return with zero exit status.
//
// FIXME: Since this function runs in its own thread,
// set_exit_status() should have a mutex.
set_exit_status(E_ERROR);
user_abort = true;
return TRUE;

View File

@ -21,7 +21,7 @@ extern volatile sig_atomic_t user_abort;
extern void signals_init(void);
#if defined(_WIN32) || defined(__VMS)
#if (defined(_WIN32) && !defined(__CYGWIN__)) || defined(__VMS)
# define signals_block() do { } while (0)
# define signals_unblock() do { } while (0)
#else
@ -34,7 +34,7 @@ extern void signals_block(void);
extern void signals_unblock(void);
#endif
#ifdef _WIN32
#if defined(_WIN32) && !defined(__CYGWIN__)
# define signals_exit() do { } while (0)
#else
/// If user has sent us a signal earlier to terminate the process,

View File

@ -14,6 +14,13 @@
#include <stdarg.h>
/// Buffers for uint64_to_str() and uint64_to_nicestr()
static char bufs[4][128];
/// Thousand separator support in uint64_to_str() and uint64_to_nicestr()
static enum { UNKNOWN, WORKS, BROKEN } thousand = UNKNOWN;
extern void *
xrealloc(void *ptr, size_t size)
{
@ -56,11 +63,17 @@ str_to_uint64(const char *name, const char *value, uint64_t min, uint64_t max)
do {
// Don't overflow.
if (result > (UINT64_MAX - 9) / 10)
if (result > UINT64_MAX / 10)
goto error;
result *= 10;
result += *value - '0';
// Another overflow check
const uint32_t add = *value - '0';
if (UINT64_MAX - add < result)
goto error;
result += add;
++value;
} while (*value >= '0' && *value <= '9');
@ -119,21 +132,27 @@ round_up_to_mib(uint64_t n)
}
/// Check if thousand separator is supported. Run-time checking is easiest,
/// because it seems to be sometimes lacking even on POSIXish system.
static void
check_thousand_sep(uint32_t slot)
{
if (thousand == UNKNOWN) {
bufs[slot][0] = '\0';
snprintf(bufs[slot], sizeof(bufs[slot]), "%'u", 1U);
thousand = bufs[slot][0] == '1' ? WORKS : BROKEN;
}
return;
}
extern const char *
uint64_to_str(uint64_t value, uint32_t slot)
{
// 2^64 with thousand separators is 26 bytes plus trailing '\0'.
static char bufs[4][32];
assert(slot < ARRAY_SIZE(bufs));
static enum { UNKNOWN, WORKS, BROKEN } thousand = UNKNOWN;
if (thousand == UNKNOWN) {
bufs[slot][0] = '\0';
snprintf(bufs[slot], sizeof(bufs[slot]), "%'" PRIu64,
UINT64_C(1));
thousand = bufs[slot][0] == '1' ? WORKS : BROKEN;
}
check_thousand_sep(slot);
if (thousand == WORKS)
snprintf(bufs[slot], sizeof(bufs[slot]), "%'" PRIu64, value);
@ -151,14 +170,21 @@ uint64_to_nicestr(uint64_t value, enum nicestr_unit unit_min,
{
assert(unit_min <= unit_max);
assert(unit_max <= NICESTR_TIB);
assert(slot < ARRAY_SIZE(bufs));
check_thousand_sep(slot);
enum nicestr_unit unit = NICESTR_B;
const char *str;
char *pos = bufs[slot];
size_t left = sizeof(bufs[slot]);
if ((unit_min == NICESTR_B && value < 10000)
|| unit_max == NICESTR_B) {
// The value is shown as bytes.
str = uint64_to_str(value, slot);
if (thousand == WORKS)
my_snprintf(&pos, &left, "%'u", (unsigned int)value);
else
my_snprintf(&pos, &left, "%u", (unsigned int)value);
} else {
// Scale the value to a nicer unit. Unless unit_min and
// unit_max limit us, we will show at most five significant
@ -169,49 +195,23 @@ uint64_to_nicestr(uint64_t value, enum nicestr_unit unit_min,
++unit;
} while (unit < unit_min || (d > 9999.9 && unit < unit_max));
str = double_to_str(d);
if (thousand == WORKS)
my_snprintf(&pos, &left, "%'.1f", d);
else
my_snprintf(&pos, &left, "%.1f", d);
}
static const char suffix[5][4] = { "B", "KiB", "MiB", "GiB", "TiB" };
my_snprintf(&pos, &left, " %s", suffix[unit]);
// Minimum buffer size:
// 26 2^64 with thousand separators
// 4 " KiB"
// 2 " ("
// 26 2^64 with thousand separators
// 3 " B)"
// 1 '\0'
// 62 Total
static char buf[4][64];
char *pos = buf[slot];
size_t left = sizeof(buf[slot]);
my_snprintf(&pos, &left, "%s %s", str, suffix[unit]);
if (always_also_bytes && value >= 10000)
snprintf(pos, left, " (%s B)", uint64_to_str(value, slot));
return buf[slot];
}
extern const char *
double_to_str(double value)
{
static char buf[64];
static enum { UNKNOWN, WORKS, BROKEN } thousand = UNKNOWN;
if (thousand == UNKNOWN) {
buf[0] = '\0';
snprintf(buf, sizeof(buf), "%'.1f", 2.0);
thousand = buf[0] == '2' ? WORKS : BROKEN;
if (always_also_bytes && value >= 10000) {
if (thousand == WORKS)
snprintf(pos, left, " (%'" PRIu64 " B)", value);
else
snprintf(pos, left, " (%" PRIu64 " B)", value);
}
if (thousand == WORKS)
snprintf(buf, sizeof(buf), "%'.1f", value);
else
snprintf(buf, sizeof(buf), "%.1f", value);
return buf;
return bufs[slot];
}
@ -225,7 +225,10 @@ my_snprintf(char **pos, size_t *left, const char *fmt, ...)
// If an error occurred, we want the caller to think that the whole
// buffer was used. This way no more data will be written to the
// buffer. We don't need better error handling here.
// buffer. We don't need better error handling here, although it
// is possible that the result looks garbage on the terminal if
// e.g. an UTF-8 character gets split. That shouldn't (easily)
// happen though, because the buffers used have some extra room.
if (len < 0 || (size_t)(len) >= *left) {
*left = 0;
} else {
@ -237,45 +240,6 @@ my_snprintf(char **pos, size_t *left, const char *fmt, ...)
}
/*
/// \brief Simple quoting to get rid of ASCII control characters
///
/// This is not so cool and locale-dependent, but should be good enough
/// At least we don't print any control characters on the terminal.
///
extern char *
str_quote(const char *str)
{
size_t dest_len = 0;
bool has_ctrl = false;
while (str[dest_len] != '\0')
if (*(unsigned char *)(str + dest_len++) < 0x20)
has_ctrl = true;
char *dest = malloc(dest_len + 1);
if (dest != NULL) {
if (has_ctrl) {
for (size_t i = 0; i < dest_len; ++i)
if (*(unsigned char *)(str + i) < 0x20)
dest[i] = '?';
else
dest[i] = str[i];
dest[dest_len] = '\0';
} else {
// Usually there are no control characters,
// so we can optimize.
memcpy(dest, str, dest_len + 1);
}
}
return dest;
}
*/
extern bool
is_empty_filename(const char *filename)
{

View File

@ -96,13 +96,6 @@ extern const char *uint64_to_nicestr(uint64_t value,
bool always_also_bytes, uint32_t slot);
/// \brief Convert double to a string with one decimal place
///
/// This is like uint64_to_str() except that this converts a double and
/// uses exactly one decimal place.
extern const char *double_to_str(double value);
/// \brief Wrapper for snprintf() to help constructing a string in pieces
///
/// A maximum of *left bytes is written starting from *pos. *pos and *left

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
.\" This file has been put into the public domain.
.\" You can do whatever you want with this file.
.\"
.TH XZDEC 1 "2010-03-07" "Tukaani" "XZ Utils"
.TH XZDEC 1 "2010-09-27" "Tukaani" "XZ Utils"
.SH NAME
xzdec, lzmadec \- Small .xz and .lzma decompressors
.SH SYNOPSIS
@ -25,7 +25,8 @@ files.
.B xzdec
is intended to work as a drop-in replacement for
.BR xz (1)
in the most common situations where a script has been written to use
in the most common situations where a script
has been written to use
.B "xz \-\-decompress \-\-stdout"
(and possibly a few other commonly used options) to decompress
.B .xz
@ -43,9 +44,12 @@ files.
.PP
To reduce the size of the executable,
.B xzdec
doesn't support multithreading or localization, and doesn't read options from
doesn't support multithreading or localization,
and doesn't read options from
.B XZ_DEFAULTS
and
.B XZ_OPT
environment variable.
environment variables.
.B xzdec
doesn't support displaying intermediate progress information: sending
.B SIGINFO
@ -77,45 +81,6 @@ compatibility.
.B xzdec
always writes the decompressed data to standard output.
.TP
\fB\-M\fR \fIlimit\fR, \fB\-\-memory=\fIlimit
Set the memory usage
.IR limit .
If this option is specified multiple times, the last one takes effect. The
.I limit
can be specified in multiple ways:
.RS
.IP \(bu 3
The
.I limit
can be an absolute value in bytes. Using an integer suffix like
.B MiB
can be useful. Example:
.B "\-\-memory=80MiB"
.IP \(bu 3
The
.I limit
can be specified as a percentage of physical RAM. Example:
.B "\-\-memory=70%"
.IP \(bu 3
The
.I limit
can be reset back to its default value by setting it to
.BR 0 .
.IP \(bu 3
The memory usage limiting can be effectively disabled by setting
.I limit
to
.BR max .
This isn't recommended. It's usually better to use, for example,
.BR \-\-memory=90% .
.RE
.IP
The current
.I limit
can be seen near the bottom of the output of the
.B \-\-help
option.
.TP
.BR \-q ", " \-\-quiet
Specifying this once does nothing since
.B xzdec
@ -127,8 +92,7 @@ Ignored for
.BR xz (1)
compatibility.
.B xzdec
never uses the exit status
.BR "2" .
never uses the exit status 2.
.TP
.BR \-h ", " \-\-help
Display a help message and exit successfully.
@ -148,18 +112,32 @@ An error occurred.
.B xzdec
doesn't have any warning messages like
.BR xz (1)
has, thus the exit status
.B 2
is not used by
has, thus the exit status 2 is not used by
.BR xzdec .
.SH NOTES
Use
.BR xz (1)
instead of
.B xzdec
or
.B lzmadec
for normal everyday use.
.B xzdec
or
.B lzmadec
are meant only for situations where it is important to have
a smaller decompressor than the full-featured
.BR xz (1).
.PP
.B xzdec
and
.B lzmadec
are not really that small. The size can be reduced further by dropping
features from liblzma at compile time, but that shouldn't usually be done
for executables distributed in typical non-embedded operating system
distributions. If you need a truly small
are not really that small.
The size can be reduced further by dropping
features from liblzma at compile time,
but that shouldn't usually be done for executables distributed
in typical non-embedded operating system distributions.
If you need a truly small
.B .xz
decompressor, consider using XZ Embedded.
.SH "SEE ALSO"

View File

@ -35,12 +35,6 @@
#endif
/// Number of bytes to use memory at maximum
static uint64_t memlimit;
/// Total amount of physical RAM
static uint64_t total_ram;
/// Error messages are suppressed if this is zero, which is the case when
/// --quiet has been given at least twice.
static unsigned int display_errors = 2;
@ -66,10 +60,6 @@ my_errorf(const char *fmt, ...)
static void lzma_attribute((noreturn))
help(void)
{
// Round up to the next MiB and do it correctly also with UINT64_MAX.
const uint64_t mem_mib = (memlimit >> 20)
+ ((memlimit & ((UINT32_C(1) << 20) - 1)) != 0);
printf(
"Usage: %s [OPTION]... [FILE]...\n"
"Uncompress files in the ." TOOL_FORMAT " format to the standard output.\n"
@ -77,7 +67,6 @@ help(void)
" -c, --stdout (ignored)\n"
" -d, --decompress (ignored)\n"
" -k, --keep (ignored)\n"
" -M, --memory=NUM use NUM bytes of memory at maximum (0 means default)\n"
" -q, --quiet specify *twice* to suppress errors\n"
" -Q, --no-warn (ignored)\n"
" -h, --help display this help and exit\n"
@ -85,11 +74,9 @@ help(void)
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
"\n"
"On this system and configuration, this program will use a maximum of roughly\n"
"%" PRIu64 " MiB RAM.\n"
"\n"
"Report bugs to <" PACKAGE_BUGREPORT "> (in English or Finnish).\n"
PACKAGE_NAME " home page: <" PACKAGE_URL ">\n", progname, mem_mib);
PACKAGE_NAME " home page: <" PACKAGE_URL ">\n", progname);
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors);
}
@ -104,117 +91,6 @@ version(void)
}
/// Find out the amount of physical memory (RAM) in the system, and set
/// the memory usage limit to the given percentage of RAM.
static void
memlimit_set_percentage(uint32_t percentage)
{
memlimit = percentage * total_ram / 100;
return;
}
/// Set the memory usage limit to give number of bytes. Zero is a special
/// value to indicate the default limit.
static void
memlimit_set(uint64_t new_memlimit)
{
if (new_memlimit != 0) {
memlimit = new_memlimit;
} else {
memlimit = 40 * total_ram / 100;
if (memlimit < UINT64_C(80) * 1024 * 1024) {
memlimit = 80 * total_ram / 100;
if (memlimit > UINT64_C(80) * 1024 * 1024)
memlimit = UINT64_C(80) * 1024 * 1024;
}
}
return;
}
/// Get the total amount of physical RAM and set the memory usage limit
/// to the default value.
static void
memlimit_init(void)
{
// If we cannot determine the amount of RAM, use the assumption
// defined by the configure script.
total_ram = lzma_physmem();
if (total_ram == 0)
total_ram = (uint64_t)(ASSUME_RAM) * 1024 * 1024;
memlimit_set(0);
return;
}
/// \brief Convert a string to uint64_t
///
/// This is rudely copied from src/xz/util.c and modified a little. :-(
///
/// \param max Return value when the string "max" was specified.
///
static uint64_t
str_to_uint64(const char *value, uint64_t max)
{
uint64_t result = 0;
// Accept special value "max".
if (strcmp(value, "max") == 0)
return max;
if (*value < '0' || *value > '9') {
my_errorf("%s: Value is not a non-negative decimal integer",
value);
exit(EXIT_FAILURE);
}
do {
// Don't overflow.
if (result > (UINT64_MAX - 9) / 10)
return UINT64_MAX;
result *= 10;
result += *value - '0';
++value;
} while (*value >= '0' && *value <= '9');
if (*value != '\0') {
// Look for suffix.
uint64_t multiplier = 0;
if (*value == 'k' || *value == 'K')
multiplier = UINT64_C(1) << 10;
else if (*value == 'm' || *value == 'M')
multiplier = UINT64_C(1) << 20;
else if (*value == 'g' || *value == 'G')
multiplier = UINT64_C(1) << 30;
++value;
// Allow also e.g. Ki, KiB, and KB.
if (*value != '\0' && strcmp(value, "i") != 0
&& strcmp(value, "iB") != 0
&& strcmp(value, "B") != 0)
multiplier = 0;
if (multiplier == 0) {
my_errorf("%s: Invalid suffix", value - 1);
exit(EXIT_FAILURE);
}
// Don't overflow here either.
if (result > UINT64_MAX / multiplier)
result = UINT64_MAX;
else
result *= multiplier;
}
return result;
}
/// Parses command line options.
static void
parse_options(int argc, char **argv)
@ -226,7 +102,6 @@ parse_options(int argc, char **argv)
{ "decompress", no_argument, NULL, 'd' },
{ "uncompress", no_argument, NULL, 'd' },
{ "keep", no_argument, NULL, 'k' },
{ "memory", required_argument, NULL, 'M' },
{ "quiet", no_argument, NULL, 'q' },
{ "no-warn", no_argument, NULL, 'Q' },
{ "help", no_argument, NULL, 'h' },
@ -245,31 +120,6 @@ parse_options(int argc, char **argv)
case 'Q':
break;
case 'M': {
// Support specifying the limit as a percentage of
// installed physical RAM.
const size_t len = strlen(optarg);
if (len > 0 && optarg[len - 1] == '%') {
// Memory limit is a percentage of total
// installed RAM.
optarg[len - 1] = '\0';
const uint64_t percentage
= str_to_uint64(optarg, 100);
if (percentage < 1 || percentage > 100) {
my_errorf("Percentage must be in "
"the range [1, 100]");
exit(EXIT_FAILURE);
}
memlimit_set_percentage(percentage);
} else {
memlimit_set(str_to_uint64(
optarg, UINT64_MAX));
}
break;
}
case 'q':
if (display_errors > 0)
--display_errors;
@ -298,13 +148,12 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
// Initialize the decoder
#ifdef LZMADEC
ret = lzma_alone_decoder(strm, memlimit);
ret = lzma_alone_decoder(strm, UINT64_MAX);
#else
ret = lzma_stream_decoder(strm, memlimit, LZMA_CONCATENATED);
ret = lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED);
#endif
// The only reasonable error here is LZMA_MEM_ERROR.
// FIXME: Maybe also LZMA_MEMLIMIT_ERROR in future?
if (ret != LZMA_OK) {
my_errorf("%s", ret == LZMA_MEM_ERROR ? strerror(ENOMEM)
: "Internal error (bug)");
@ -392,10 +241,6 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
msg = strerror(ENOMEM);
break;
case LZMA_MEMLIMIT_ERROR:
msg = "Memory usage limit reached";
break;
case LZMA_FORMAT_ERROR:
msg = "File format not recognized";
break;
@ -431,10 +276,6 @@ main(int argc, char **argv)
// Initialize progname which we will be used in error messages.
tuklib_progname_init(argv);
// Set the default memory usage limit. This is needed before parsing
// the command line arguments.
memlimit_init();
// Parse the command line options.
parse_options(argc, argv);