xz: Show minimum required XZ Utils version in xz -lvv.

Man page wasn't updated yet.
This commit is contained in:
Lasse Collin 2011-11-07 13:07:52 +02:00
parent 7081d82c37
commit 418fe668b3
1 changed files with 57 additions and 6 deletions

View File

@ -29,9 +29,12 @@ typedef struct {
/// Uncompressed Size fields /// Uncompressed Size fields
bool all_have_sizes; bool all_have_sizes;
/// Oldest XZ Utils version that will decompress the file
uint32_t min_version;
} xz_file_info; } xz_file_info;
#define XZ_FILE_INFO_INIT { NULL, 0, 0, true } #define XZ_FILE_INFO_INIT { NULL, 0, 0, true, 50000002 }
/// Information about a .xz Block /// Information about a .xz Block
@ -104,8 +107,32 @@ static struct {
uint64_t stream_padding; uint64_t stream_padding;
uint64_t memusage_max; uint64_t memusage_max;
uint32_t checks; uint32_t checks;
uint32_t min_version;
bool all_have_sizes; bool all_have_sizes;
} totals = { 0, 0, 0, 0, 0, 0, 0, 0, true }; } totals = { 0, 0, 0, 0, 0, 0, 0, 0, 0, true };
/// Convert XZ Utils version number to a string.
static const char *
xz_ver_to_str(uint32_t ver)
{
static char buf[32];
unsigned int major = ver / 10000000U;
ver -= major * 10000000U;
unsigned int minor = ver / 10000U;
ver -= minor * 10000U;
unsigned int patch = ver / 10U;
ver -= patch * 10U;
const char *stability = ver == 0 ? "alpha" : ver == 1 ? "beta" : "";
snprintf(buf, sizeof(buf), "%u.%u.%u%s",
major, minor, patch, stability);
return buf;
}
/// \brief Parse the Index(es) from the given .xz file /// \brief Parse the Index(es) from the given .xz file
@ -452,6 +479,21 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
if (xfi->memusage_max < bhi->memusage) if (xfi->memusage_max < bhi->memusage)
xfi->memusage_max = bhi->memusage; xfi->memusage_max = bhi->memusage;
// Determine the minimum XZ Utils version that supports this Block.
//
// Currently the only thing that 5.0.0 doesn't support is empty
// LZMA2 Block. This bug was fixed in 5.0.3.
{
size_t i = 0;
while (filters[i + 1].id != LZMA_VLI_UNKNOWN)
++i;
if (filters[i].id == LZMA_FILTER_LZMA2
&& iter->block.uncompressed_size == 0
&& xfi->min_version < 50000032U)
xfi->min_version = 50000032U;
}
// Convert the filter chain to human readable form. // Convert the filter chain to human readable form.
message_filters_to_str(bhi->filter_chain, filters, false); message_filters_to_str(bhi->filter_chain, filters, false);
@ -830,6 +872,8 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
round_up_to_mib(xfi->memusage_max), 0)); round_up_to_mib(xfi->memusage_max), 0));
printf(_(" Sizes in headers: %s\n"), printf(_(" Sizes in headers: %s\n"),
xfi->all_have_sizes ? _("Yes") : _("No")); xfi->all_have_sizes ? _("Yes") : _("No"));
printf(_(" Minimum XZ Utils version: %s\n"),
xz_ver_to_str(xfi->min_version));
} }
return false; return false;
@ -912,9 +956,10 @@ print_info_robot(xz_file_info *xfi, file_pair *pair)
} }
if (message_verbosity_get() >= V_DEBUG) if (message_verbosity_get() >= V_DEBUG)
printf("summary\t%" PRIu64 "\t%s\n", printf("summary\t%" PRIu64 "\t%s\t%" PRIu32 "\n",
xfi->memusage_max, xfi->memusage_max,
xfi->all_have_sizes ? "yes" : "no"); xfi->all_have_sizes ? "yes" : "no",
xfi->min_version);
return false; return false;
} }
@ -935,6 +980,9 @@ update_totals(const xz_file_info *xfi)
if (totals.memusage_max < xfi->memusage_max) if (totals.memusage_max < xfi->memusage_max)
totals.memusage_max = xfi->memusage_max; totals.memusage_max = xfi->memusage_max;
if (totals.min_version < xfi->min_version)
totals.min_version = xfi->min_version;
totals.all_have_sizes &= xfi->all_have_sizes; totals.all_have_sizes &= xfi->all_have_sizes;
return; return;
@ -999,6 +1047,8 @@ print_totals_adv(void)
round_up_to_mib(totals.memusage_max), 0)); round_up_to_mib(totals.memusage_max), 0));
printf(_(" Sizes in headers: %s\n"), printf(_(" Sizes in headers: %s\n"),
totals.all_have_sizes ? _("Yes") : _("No")); totals.all_have_sizes ? _("Yes") : _("No"));
printf(_(" Minimum XZ Utils version: %s\n"),
xz_ver_to_str(totals.min_version));
} }
return; return;
@ -1024,9 +1074,10 @@ print_totals_robot(void)
totals.files); totals.files);
if (message_verbosity_get() >= V_DEBUG) if (message_verbosity_get() >= V_DEBUG)
printf("\t%" PRIu64 "\t%s", printf("\t%" PRIu64 "\t%s\t%" PRIu32,
totals.memusage_max, totals.memusage_max,
totals.all_have_sizes ? "yes" : "no"); totals.all_have_sizes ? "yes" : "no",
totals.min_version);
putchar('\n'); putchar('\n');