mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
Initial changes to change the suffix of the new format to .xz.
This also fixes a bug related to --suffix option. Some issues with suffixes with --format=raw were not fixed.
This commit is contained in:
parent
4c321a41c4
commit
bd137524f2
6 changed files with 133 additions and 52 deletions
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
|
|
||||||
enum tool_mode opt_mode = MODE_COMPRESS;
|
enum tool_mode opt_mode = MODE_COMPRESS;
|
||||||
enum header_type opt_header = HEADER_AUTO;
|
enum format_type opt_format = FORMAT_AUTO;
|
||||||
|
|
||||||
char *opt_suffix = NULL;
|
char *opt_suffix = NULL;
|
||||||
|
|
||||||
|
@ -50,6 +50,12 @@ static size_t preset_number = 7 - 1;
|
||||||
static bool preset_default = true;
|
static bool preset_default = true;
|
||||||
static size_t filter_count = 0;
|
static size_t filter_count = 0;
|
||||||
|
|
||||||
|
/// When compressing, which file format to use if --format=auto or no --format
|
||||||
|
/// at all has been specified. We need a variable because this depends on
|
||||||
|
/// with which name we are called. All names with "lz" in them makes us to
|
||||||
|
/// use the legacy .lzma format.
|
||||||
|
static enum format_type format_compress_auto = FORMAT_XZ;
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
OPT_SUBBLOCK = INT_MIN,
|
OPT_SUBBLOCK = INT_MIN,
|
||||||
|
@ -312,18 +318,25 @@ parse_real(int argc, char **argv)
|
||||||
|
|
||||||
// --format
|
// --format
|
||||||
case 'F': {
|
case 'F': {
|
||||||
static const char *types[] = {
|
// Just in case, support both "lzma" and "alone" since
|
||||||
"auto",
|
// the latter was used for forward compatibility in
|
||||||
"native",
|
// LZMA Utils 4.32.x.
|
||||||
"alone",
|
static const struct {
|
||||||
// "gzip",
|
char str[8];
|
||||||
"raw",
|
enum format_type format;
|
||||||
NULL
|
} types[] = {
|
||||||
|
{ "auto", FORMAT_AUTO },
|
||||||
|
{ "xz", FORMAT_XZ },
|
||||||
|
{ "lzma", FORMAT_LZMA },
|
||||||
|
{ "alone", FORMAT_LZMA },
|
||||||
|
// { "gzip", FORMAT_GZIP },
|
||||||
|
// { "gz", FORMAT_GZIP },
|
||||||
|
{ "raw", FORMAT_RAW },
|
||||||
};
|
};
|
||||||
|
|
||||||
opt_header = 0;
|
size_t i = 0;
|
||||||
while (strcmp(types[opt_header], optarg) != 0) {
|
while (strcmp(types[i].str, optarg) != 0) {
|
||||||
if (types[++opt_header] == NULL) {
|
if (++i == ARRAY_SIZE(types)) {
|
||||||
errmsg(V_ERROR, _("%s: Unknown file "
|
errmsg(V_ERROR, _("%s: Unknown file "
|
||||||
"format type"),
|
"format type"),
|
||||||
optarg);
|
optarg);
|
||||||
|
@ -331,25 +344,25 @@ parse_real(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opt_format = types[i].format;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --check
|
// --check
|
||||||
case 'C': {
|
case 'C': {
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *str;
|
char str[8];
|
||||||
unsigned int value;
|
lzma_check check;
|
||||||
} types[] = {
|
} types[] = {
|
||||||
{ "none", LZMA_CHECK_NONE },
|
{ "none", LZMA_CHECK_NONE },
|
||||||
{ "crc32", LZMA_CHECK_CRC32 },
|
{ "crc32", LZMA_CHECK_CRC32 },
|
||||||
{ "crc64", LZMA_CHECK_CRC64 },
|
{ "crc64", LZMA_CHECK_CRC64 },
|
||||||
{ "sha256", LZMA_CHECK_SHA256 },
|
{ "sha256", LZMA_CHECK_SHA256 },
|
||||||
{ NULL, 0 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (strcmp(types[i].str, optarg) != 0) {
|
while (strcmp(types[i].str, optarg) != 0) {
|
||||||
if (types[++i].str == NULL) {
|
if (++i == ARRAY_SIZE(types)) {
|
||||||
errmsg(V_ERROR, _("%s: Unknown "
|
errmsg(V_ERROR, _("%s: Unknown "
|
||||||
"integrity check "
|
"integrity check "
|
||||||
"type"), optarg);
|
"type"), optarg);
|
||||||
|
@ -357,7 +370,7 @@ parse_real(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_check = types[i].value;
|
opt_check = types[i].check;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +473,7 @@ set_compression_settings(void)
|
||||||
my_exit(ERROR);
|
my_exit(ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_filters[0].id = opt_header == HEADER_ALONE
|
opt_filters[0].id = opt_format == FORMAT_LZMA
|
||||||
? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2;
|
? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2;
|
||||||
opt_filters[0].options = &opt_lzma;
|
opt_filters[0].options = &opt_lzma;
|
||||||
filter_count = 1;
|
filter_count = 1;
|
||||||
|
@ -471,9 +484,9 @@ set_compression_settings(void)
|
||||||
|
|
||||||
// If we are using the LZMA_Alone format, allow exactly one filter
|
// If we are using the LZMA_Alone format, allow exactly one filter
|
||||||
// which has to be LZMA.
|
// which has to be LZMA.
|
||||||
if (opt_header == HEADER_ALONE && (filter_count != 1
|
if (opt_format == FORMAT_LZMA && (filter_count != 1
|
||||||
|| opt_filters[0].id != LZMA_FILTER_LZMA1)) {
|
|| opt_filters[0].id != LZMA_FILTER_LZMA1)) {
|
||||||
errmsg(V_ERROR, _("With --format=alone only the LZMA1 filter "
|
errmsg(V_ERROR, _("With --format=lzma only the LZMA1 filter "
|
||||||
"is supported"));
|
"is supported"));
|
||||||
my_exit(ERROR);
|
my_exit(ERROR);
|
||||||
}
|
}
|
||||||
|
@ -503,6 +516,12 @@ set_compression_settings(void)
|
||||||
|
|
||||||
memory_usage = lzma_memusage_encoder(opt_filters);
|
memory_usage = lzma_memusage_encoder(opt_filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: With --format=raw, we should print a warning since
|
||||||
|
// the presets may change and thus the next version may not
|
||||||
|
// be able to uncompress the raw stream with the same preset
|
||||||
|
// number.
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (memory_usage > opt_memory) {
|
if (memory_usage > opt_memory) {
|
||||||
errmsg(V_ERROR, _("Memory usage limit is too small "
|
errmsg(V_ERROR, _("Memory usage limit is too small "
|
||||||
|
@ -532,6 +551,11 @@ parse_args(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *name = str_filename(argv[0]);
|
const char *name = str_filename(argv[0]);
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
|
// Default file format
|
||||||
|
if (strstr(name, "lz") != NULL)
|
||||||
|
format_compress_auto = FORMAT_LZMA;
|
||||||
|
|
||||||
|
// Operation mode
|
||||||
if (strstr(name, "cat") != NULL) {
|
if (strstr(name, "cat") != NULL) {
|
||||||
opt_mode = MODE_DECOMPRESS;
|
opt_mode = MODE_DECOMPRESS;
|
||||||
opt_stdout = true;
|
opt_stdout = true;
|
||||||
|
@ -556,7 +580,10 @@ parse_args(int argc, char **argv)
|
||||||
opt_stdout = true;
|
opt_stdout = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_mode == MODE_COMPRESS || opt_header == HEADER_RAW)
|
if (opt_mode == MODE_COMPRESS && opt_format == FORMAT_AUTO)
|
||||||
|
opt_format = format_compress_auto;
|
||||||
|
|
||||||
|
if (opt_mode == MODE_COMPRESS || opt_format == FORMAT_RAW)
|
||||||
set_compression_settings();
|
set_compression_settings();
|
||||||
|
|
||||||
// If no filenames are given, use stdin.
|
// If no filenames are given, use stdin.
|
||||||
|
|
|
@ -30,12 +30,13 @@ enum tool_mode {
|
||||||
MODE_LIST,
|
MODE_LIST,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum header_type {
|
// NOTE: The order of these is significant in suffix.c.
|
||||||
HEADER_AUTO,
|
enum format_type {
|
||||||
HEADER_NATIVE,
|
FORMAT_AUTO,
|
||||||
HEADER_ALONE,
|
FORMAT_XZ,
|
||||||
|
FORMAT_LZMA,
|
||||||
// HEADER_GZIP,
|
// HEADER_GZIP,
|
||||||
HEADER_RAW,
|
FORMAT_RAW,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ extern bool opt_keep_original;
|
||||||
extern bool opt_preserve_name;
|
extern bool opt_preserve_name;
|
||||||
// extern bool opt_recursive;
|
// extern bool opt_recursive;
|
||||||
extern enum tool_mode opt_mode;
|
extern enum tool_mode opt_mode;
|
||||||
extern enum header_type opt_header;
|
extern enum format_type opt_format;
|
||||||
|
|
||||||
extern lzma_check opt_check;
|
extern lzma_check opt_check;
|
||||||
extern lzma_filter opt_filters[8];
|
extern lzma_filter opt_filters[8];
|
||||||
|
|
|
@ -46,7 +46,7 @@ show_help(void)
|
||||||
" -z, --compress force compression\n"
|
" -z, --compress force compression\n"
|
||||||
" -d, --decompress force decompression\n"
|
" -d, --decompress force decompression\n"
|
||||||
" -t, --test test compressed file integrity\n"
|
" -t, --test test compressed file integrity\n"
|
||||||
" -l, --list list block sizes, total sizes, and possible metadata\n"
|
" -l, --list list information about files\n"
|
||||||
));
|
));
|
||||||
|
|
||||||
puts(_(
|
puts(_(
|
||||||
|
@ -57,7 +57,7 @@ show_help(void)
|
||||||
" -c, --stdout write to standard output and don't delete input files\n"
|
" -c, --stdout write to standard output and don't delete input files\n"
|
||||||
" -S, --suffix=.SUF use suffix `.SUF' on compressed files instead of `.lzma'\n"
|
" -S, --suffix=.SUF use suffix `.SUF' on compressed files instead of `.lzma'\n"
|
||||||
" -F, --format=FMT file format to encode or decode; possible values are\n"
|
" -F, --format=FMT file format to encode or decode; possible values are\n"
|
||||||
" `auto' (default), `native', `alone', and `raw'\n"
|
" `auto' (default), `xz', `lzma', and `raw'\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"
|
" omitted, filenames are read from the standard input;\n"
|
||||||
" filenames must be terminated with the newline character\n"
|
" filenames must be terminated with the newline character\n"
|
||||||
|
|
|
@ -155,19 +155,23 @@ single_init(thread_data *t)
|
||||||
lzma_ret ret = LZMA_PROG_ERROR;
|
lzma_ret ret = LZMA_PROG_ERROR;
|
||||||
|
|
||||||
if (opt_mode == MODE_COMPRESS) {
|
if (opt_mode == MODE_COMPRESS) {
|
||||||
switch (opt_header) {
|
switch (opt_format) {
|
||||||
case HEADER_AUTO:
|
case FORMAT_AUTO:
|
||||||
case HEADER_NATIVE:
|
// args.c ensures this.
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FORMAT_XZ:
|
||||||
ret = lzma_stream_encoder(&t->strm,
|
ret = lzma_stream_encoder(&t->strm,
|
||||||
opt_filters, opt_check);
|
opt_filters, opt_check);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEADER_ALONE:
|
case FORMAT_LZMA:
|
||||||
ret = lzma_alone_encoder(&t->strm,
|
ret = lzma_alone_encoder(&t->strm,
|
||||||
opt_filters[0].options);
|
opt_filters[0].options);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEADER_RAW:
|
case FORMAT_RAW:
|
||||||
ret = lzma_raw_encoder(&t->strm, opt_filters);
|
ret = lzma_raw_encoder(&t->strm, opt_filters);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -175,20 +179,20 @@ single_init(thread_data *t)
|
||||||
const uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK
|
const uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK
|
||||||
| LZMA_CONCATENATED;
|
| LZMA_CONCATENATED;
|
||||||
|
|
||||||
switch (opt_header) {
|
switch (opt_format) {
|
||||||
case HEADER_AUTO:
|
case FORMAT_AUTO:
|
||||||
ret = lzma_auto_decoder(&t->strm, opt_memory, flags);
|
ret = lzma_auto_decoder(&t->strm, opt_memory, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEADER_NATIVE:
|
case FORMAT_XZ:
|
||||||
ret = lzma_stream_decoder(&t->strm, opt_memory, flags);
|
ret = lzma_stream_decoder(&t->strm, opt_memory, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEADER_ALONE:
|
case FORMAT_LZMA:
|
||||||
ret = lzma_alone_decoder(&t->strm, opt_memory);
|
ret = lzma_alone_decoder(&t->strm, opt_memory);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HEADER_RAW:
|
case FORMAT_RAW:
|
||||||
// Memory usage has already been checked in args.c.
|
// Memory usage has already been checked in args.c.
|
||||||
ret = lzma_raw_decoder(&t->strm, opt_filters);
|
ret = lzma_raw_decoder(&t->strm, opt_filters);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,14 +20,9 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
|
|
||||||
static const struct {
|
struct suffix_pair {
|
||||||
const char *compressed;
|
const char *compressed;
|
||||||
const char *uncompressed;
|
const char *uncompressed;
|
||||||
} suffixes[] = {
|
|
||||||
{ ".lzma", "" },
|
|
||||||
{ ".tlz", ".tar" },
|
|
||||||
{ ".ylz", ".yar" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,13 +58,21 @@ test_suffix(const char *suffix, const char *src_name, size_t src_len)
|
||||||
/// \return Name of the uncompressed file, or NULL if file has unknown
|
/// \return Name of the uncompressed file, or NULL if file has unknown
|
||||||
/// suffix.
|
/// suffix.
|
||||||
static char *
|
static char *
|
||||||
uncompressed_name(const char *src_name)
|
uncompressed_name(const char *src_name, const size_t src_len)
|
||||||
{
|
{
|
||||||
|
static const struct suffix_pair suffixes[] = {
|
||||||
|
{ ".xz", "" },
|
||||||
|
{ ".txz", ".tar" }, // .txz abbreviation for .txt.gz is rare.
|
||||||
|
{ ".lzma", "" },
|
||||||
|
{ ".tlz", ".tar" },
|
||||||
|
// { ".gz", "" },
|
||||||
|
// { ".tgz", ".tar" },
|
||||||
|
};
|
||||||
|
|
||||||
const char *new_suffix = "";
|
const char *new_suffix = "";
|
||||||
const size_t src_len = strlen(src_name);
|
|
||||||
size_t new_len = 0;
|
size_t new_len = 0;
|
||||||
|
|
||||||
for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
|
for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) {
|
||||||
new_len = test_suffix(suffixes[i].compressed,
|
new_len = test_suffix(suffixes[i].compressed,
|
||||||
src_name, src_len);
|
src_name, src_len);
|
||||||
if (new_len != 0) {
|
if (new_len != 0) {
|
||||||
|
@ -103,10 +106,40 @@ uncompressed_name(const char *src_name)
|
||||||
|
|
||||||
|
|
||||||
/// \brief Appends suffix to src_name
|
/// \brief Appends suffix to src_name
|
||||||
|
///
|
||||||
|
/// In contrast to uncompressed_name(), we check only suffixes that are valid
|
||||||
|
/// for the specified file format.
|
||||||
static char *
|
static char *
|
||||||
compressed_name(const char *src_name)
|
compressed_name(const char *src_name, const size_t src_len)
|
||||||
{
|
{
|
||||||
const size_t src_len = strlen(src_name);
|
// The order of these must match the order in args.h.
|
||||||
|
static const struct suffix_pair all_suffixes[][3] = {
|
||||||
|
{
|
||||||
|
{ ".xz", "" },
|
||||||
|
{ ".txz", ".tar" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
}, {
|
||||||
|
{ ".lzma", "" },
|
||||||
|
{ ".tlz", ".tar" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
/*
|
||||||
|
}, {
|
||||||
|
{ ".gz", "" },
|
||||||
|
{ ".tgz", ".tar" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
// --format=raw requires specifying the suffix
|
||||||
|
// manually or using stdout.
|
||||||
|
{ NULL, NULL }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// args.c ensures this.
|
||||||
|
assert(opt_format != FORMAT_AUTO);
|
||||||
|
|
||||||
|
const size_t format = opt_format - 1;
|
||||||
|
const struct suffix_pair *const suffixes = all_suffixes[format];
|
||||||
|
|
||||||
for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
|
for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
|
||||||
if (test_suffix(suffixes[i].compressed, src_name, src_len)
|
if (test_suffix(suffixes[i].compressed, src_name, src_len)
|
||||||
|
@ -118,6 +151,15 @@ compressed_name(const char *src_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Hmm, maybe it would be better to validate this in args.c,
|
||||||
|
// since the suffix handling when decoding is weird now.
|
||||||
|
if (opt_format == FORMAT_RAW && opt_suffix == NULL) {
|
||||||
|
errmsg(V_ERROR, _("%s: With --format=raw, --suffix=.SUF is "
|
||||||
|
"required unless writing to stdout"),
|
||||||
|
src_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const char *suffix = opt_suffix != NULL
|
const char *suffix = opt_suffix != NULL
|
||||||
? opt_suffix : suffixes[0].compressed;
|
? opt_suffix : suffixes[0].compressed;
|
||||||
const size_t suffix_len = strlen(suffix);
|
const size_t suffix_len = strlen(suffix);
|
||||||
|
@ -139,7 +181,13 @@ compressed_name(const char *src_name)
|
||||||
extern char *
|
extern char *
|
||||||
get_dest_name(const char *src_name)
|
get_dest_name(const char *src_name)
|
||||||
{
|
{
|
||||||
|
assert(src_name != NULL);
|
||||||
|
|
||||||
|
// Length of the name is needed in all cases to locate the end of
|
||||||
|
// the string to compare the suffix, so calculate the length here.
|
||||||
|
const size_t src_len = strlen(src_name);
|
||||||
|
|
||||||
return opt_mode == MODE_COMPRESS
|
return opt_mode == MODE_COMPRESS
|
||||||
? compressed_name(src_name)
|
? compressed_name(src_name, src_len)
|
||||||
: uncompressed_name(src_name);
|
: uncompressed_name(src_name, src_len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,8 @@ test_lzma() {
|
||||||
echo . | tr -d '\n\r'
|
echo . | tr -d '\n\r'
|
||||||
}
|
}
|
||||||
|
|
||||||
LZMA="../src/lzma/lzma --memory=15Mi --threads=1"
|
# TODO: Remove --format=xz once the command name has been changed.
|
||||||
|
LZMA="../src/lzma/lzma --memory=15Mi --threads=1 --format=xz"
|
||||||
LZMADEC="../src/lzmadec/lzmadec --memory=4Mi"
|
LZMADEC="../src/lzmadec/lzmadec --memory=4Mi"
|
||||||
unset LZMA_OPT
|
unset LZMA_OPT
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue