Vendor import of xz (stripped)
Git revision: d52b411716a614c202e89ba732492efb9916cd3f Approved by: delphij (mentor)
This commit is contained in:
parent
1008b7c674
commit
2801acca20
814
ChangeLog
814
ChangeLog
@ -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
37
FREEBSD-Xlist
Normal 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
28
FREEBSD-upgrade
Normal 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
98
README
@ -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
6
THANKS
@ -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
|
||||
|
@ -1 +1,3 @@
|
||||
cs
|
||||
de
|
||||
it
|
||||
|
@ -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
|
||||
|
903
po/de.po
Normal file
903
po/de.po
Normal 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
902
po/it.po
Normal 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"
|
@ -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]))
|
||||
|
@ -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;
|
||||
|
@ -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
66
src/common/tuklib_mbstr.h
Normal 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
|
31
src/common/tuklib_mbstr_fw.c
Normal file
31
src/common/tuklib_mbstr_fw.c
Normal 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;
|
||||
}
|
64
src/common/tuklib_mbstr_width.c
Normal file
64
src/common/tuklib_mbstr_width.c
Normal 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
|
||||
}
|
@ -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) {
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
@ -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;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
109
src/xz/args.c
109
src/xz/args.c
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
828
src/xz/list.c
828
src/xz/list.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
|
326
src/xz/message.c
326
src/xz/message.c
@ -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
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
146
src/xz/util.c
146
src/xz/util.c
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
2350
src/xz/xz.1
2350
src/xz/xz.1
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user