aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xz/list.c263
1 files changed, 212 insertions, 51 deletions
diff --git a/src/xz/list.c b/src/xz/list.c
index 98809b59..c20beadd 100644
--- a/src/xz/list.c
+++ b/src/xz/list.c
@@ -100,6 +100,63 @@ static int colon_strs_fw[ARRAY_SIZE(colon_strs)];
#define COLON_STR(num) colon_strs_fw[num], _(colon_strs[num])
+/// Column headings
+struct {
+ /// Table column heading string
+ const char *str;
+
+ /// Number of terminal-columns to use for this table-column.
+ /// If a translated string is longer than the initial value,
+ /// this value will be increased in init_headings().
+ int columns;
+
+ /// Field width to use for printf() to pad "str" to use "columns"
+ /// number of columns on a terminal. This is calculated in
+ /// init_headings().
+ int fw;
+
+} headings[] = {
+ { N_("Stream"), 6, 0 },
+ { N_("Block"), 9, 0 },
+ { N_("Blocks"), 9, 0 },
+ { N_("CompOffset"), 15, 0 },
+ { N_("UncompOffset"), 15, 0 },
+ { N_("CompSize"), 15, 0 },
+ { N_("UncompSize"), 15, 0 },
+ { N_("TotalSize"), 15, 0 },
+ { N_("Ratio"), 5, 0 },
+ { N_("Check"), 10, 0 },
+ { N_("CheckVal"), 1, 0 },
+ { N_("Padding"), 7, 0 },
+ { N_("Header"), 5, 0 },
+ { N_("Flags"), 2, 0 },
+ { N_("MemUsage"), 7 + 4, 0 }, // +4 is for " MiB"
+ { N_("Filters"), 1, 0 },
+};
+
+/// Enum matching the above strings.
+enum {
+ HEADING_STREAM,
+ HEADING_BLOCK,
+ HEADING_BLOCKS,
+ HEADING_COMPOFFSET,
+ HEADING_UNCOMPOFFSET,
+ HEADING_COMPSIZE,
+ HEADING_UNCOMPSIZE,
+ HEADING_TOTALSIZE,
+ HEADING_RATIO,
+ HEADING_CHECK,
+ HEADING_CHECKVAL,
+ HEADING_PADDING,
+ HEADING_HEADERSIZE,
+ HEADING_HEADERFLAGS,
+ HEADING_MEMUSAGE,
+ HEADING_FILTERS,
+};
+
+#define HEADING_STR(num) headings[num].fw, _(headings[num].str)
+
+
/// Check ID to string mapping
static const char check_names[LZMA_CHECK_ID_MAX + 1][12] = {
// TRANSLATORS: Indicates that there is no integrity check.
@@ -155,10 +212,9 @@ static struct {
} totals = { 0, 0, 0, 0, 0, 0, 0, 0, 50000002, true };
-/// Initialize the printf field widths that are needed to get nicely aligned
-/// output with translated strings.
+/// Initialize colon_strs_fw[].
static void
-init_field_widths(void)
+init_colon_strs(void)
{
// Lengths of translated strings as bytes.
size_t lens[ARRAY_SIZE(colon_strs)];
@@ -196,6 +252,44 @@ init_field_widths(void)
}
+/// Initialize headings[].
+static void
+init_headings(void)
+{
+ for (unsigned i = 0; i < ARRAY_SIZE(headings); ++i) {
+ size_t len;
+ size_t w = tuklib_mbstr_width(headings[i].str, &len);
+
+ // Error handling like in init_colon_strs().
+ assert(w != (size_t)-1);
+ if (w == (size_t)-1)
+ w = len;
+
+ // If the translated string is wider than the minimum width
+ // set at compile time, increase the width.
+ if ((size_t)(headings[i].columns) < w)
+ headings[i].columns = w;
+
+ // Calculate the field width for printf("%*s") so that
+ // the string uses .columns number of columns on a terminal.
+ headings[i].fw = (int)(len + headings[i].columns - w);
+ }
+
+ return;
+}
+
+
+/// Initialize the printf field widths that are needed to get nicely aligned
+/// output with translated strings.
+static void
+init_field_widths(void)
+{
+ init_colon_strs();
+ init_headings();
+ return;
+}
+
+
/// Convert XZ Utils version number to a string.
static const char *
xz_ver_to_str(uint32_t ver)
@@ -372,6 +466,10 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
// Check the Block Flags. These must be done before calling
// lzma_block_compressed_size(), because it overwrites
// block.compressed_size.
+ //
+ // NOTE: If you add new characters here, update the minimum number of
+ // columns in headings[HEADING_HEADERFLAGS] to match the number of
+ // characters used here.
bhi->flags[0] = block.compressed_size != LZMA_VLI_UNKNOWN
? 'c' : '-';
bhi->flags[1] = block.uncompressed_size != LZMA_VLI_UNKNOWN
@@ -670,13 +768,19 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
// Print information about the Streams.
//
- // TRANSLATORS: The second line is column headings. All except
- // Check are right aligned; Check is left aligned. Test with
- // "xz -lv foo.xz".
- puts(_(" Streams:\n Stream Blocks"
- " CompOffset UncompOffset"
- " CompSize UncompSize Ratio"
- " Check Padding"));
+ // All except Check are right aligned; Check is left aligned.
+ // Test with "xz -lv foo.xz".
+ printf(" %s\n %*s %*s %*s %*s %*s %*s %*s %-*s %*s\n",
+ _(colon_strs[COLON_STR_STREAMS]),
+ HEADING_STR(HEADING_STREAM),
+ HEADING_STR(HEADING_BLOCKS),
+ HEADING_STR(HEADING_COMPOFFSET),
+ HEADING_STR(HEADING_UNCOMPOFFSET),
+ HEADING_STR(HEADING_COMPSIZE),
+ HEADING_STR(HEADING_UNCOMPSIZE),
+ HEADING_STR(HEADING_RATIO),
+ HEADING_STR(HEADING_CHECK),
+ HEADING_STR(HEADING_PADDING));
lzma_index_iter iter;
lzma_index_iter_init(&iter, xfi->idx);
@@ -689,10 +793,18 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
uint64_to_str(iter.stream.uncompressed_offset, 3),
};
printf(" %*s %*s %*s %*s ",
- tuklib_mbstr_fw(cols1[0], 6), cols1[0],
- tuklib_mbstr_fw(cols1[1], 9), cols1[1],
- tuklib_mbstr_fw(cols1[2], 15), cols1[2],
- tuklib_mbstr_fw(cols1[3], 15), cols1[3]);
+ tuklib_mbstr_fw(cols1[0],
+ headings[HEADING_STREAM].columns),
+ cols1[0],
+ tuklib_mbstr_fw(cols1[1],
+ headings[HEADING_BLOCKS].columns),
+ cols1[1],
+ tuklib_mbstr_fw(cols1[2],
+ headings[HEADING_COMPOFFSET].columns),
+ cols1[2],
+ tuklib_mbstr_fw(cols1[3],
+ headings[HEADING_UNCOMPOFFSET].columns),
+ cols1[3]);
const char *cols2[5] = {
uint64_to_str(iter.stream.compressed_size, 0),
@@ -703,11 +815,21 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
uint64_to_str(iter.stream.padding, 2),
};
printf("%*s %*s %*s %-*s %*s\n",
- tuklib_mbstr_fw(cols2[0], 15), cols2[0],
- tuklib_mbstr_fw(cols2[1], 15), cols2[1],
- tuklib_mbstr_fw(cols2[2], 5), cols2[2],
- tuklib_mbstr_fw(cols2[3], 10), cols2[3],
- tuklib_mbstr_fw(cols2[4], 7), cols2[4]);
+ tuklib_mbstr_fw(cols2[0],
+ headings[HEADING_COMPSIZE].columns),
+ cols2[0],
+ tuklib_mbstr_fw(cols2[1],
+ headings[HEADING_UNCOMPSIZE].columns),
+ cols2[1],
+ tuklib_mbstr_fw(cols2[2],
+ headings[HEADING_RATIO].columns),
+ cols2[2],
+ tuklib_mbstr_fw(cols2[3],
+ headings[HEADING_CHECK].columns),
+ cols2[3],
+ tuklib_mbstr_fw(cols2[4],
+ headings[HEADING_PADDING].columns),
+ cols2[4]);
// Update the maximum Check size.
if (lzma_check_size(iter.stream.flags->check) > check_max)
@@ -723,26 +845,43 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
// Print information about the Blocks but only if there is
// at least one Block.
if (lzma_index_block_count(xfi->idx) > 0) {
- // Calculate the width of the CheckVal field.
- const int checkval_width = my_max(8, 2 * check_max);
-
- // TRANSLATORS: The second line is column headings. All
- // except Check are right aligned; Check is left aligned.
- printf(_(" Blocks:\n Stream Block"
- " CompOffset UncompOffset"
- " TotalSize UncompSize Ratio Check"));
+ // Calculate the width of the CheckVal column. This can be
+ // used as is as the field width for printf() when printing
+ // the actual check value as it is hexadecimal. However, to
+ // print the column heading, further calculation is needed
+ // to handle a translated string (it's done a few lines later).
+ const int checkval_width = my_max(
+ (uint32_t)(headings[HEADING_CHECKVAL].columns),
+ 2 * check_max);
+
+ // All except Check are right aligned; Check is left aligned.
+ printf(" %s\n %*s %*s %*s %*s %*s %*s %*s %-*s",
+ _(colon_strs[COLON_STR_BLOCKS]),
+ HEADING_STR(HEADING_STREAM),
+ HEADING_STR(HEADING_BLOCK),
+ HEADING_STR(HEADING_COMPOFFSET),
+ HEADING_STR(HEADING_UNCOMPOFFSET),
+ HEADING_STR(HEADING_TOTALSIZE),
+ HEADING_STR(HEADING_UNCOMPSIZE),
+ HEADING_STR(HEADING_RATIO),
+ detailed ? headings[HEADING_CHECK].fw : 1,
+ _(headings[HEADING_CHECK].str));
if (detailed) {
- // 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".
- printf(_(" CheckVal %*s Header Flags "
- "CompSize MemUsage Filters"),
- checkval_width - 8, "");
+ // CheckVal (Check value), Flags, and Filters are
+ // left aligned. Block Header Size, CompSize, and
+ // MemUsage are right aligned. Test with
+ // "xz -lvv foo.xz".
+ printf(" %-*s %*s %-*s %*s %*s %s",
+ headings[HEADING_CHECKVAL].fw
+ + checkval_width
+ - headings[HEADING_CHECKVAL].columns,
+ _(headings[HEADING_CHECKVAL].str),
+ HEADING_STR(HEADING_HEADERSIZE),
+ HEADING_STR(HEADING_HEADERFLAGS),
+ HEADING_STR(HEADING_COMPSIZE),
+ HEADING_STR(HEADING_MEMUSAGE),
+ _(headings[HEADING_FILTERS].str));
}
putchar('\n');
@@ -764,10 +903,18 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
iter.block.uncompressed_file_offset, 3)
};
printf(" %*s %*s %*s %*s ",
- tuklib_mbstr_fw(cols1[0], 6), cols1[0],
- tuklib_mbstr_fw(cols1[1], 9), cols1[1],
- tuklib_mbstr_fw(cols1[2], 15), cols1[2],
- tuklib_mbstr_fw(cols1[3], 15), cols1[3]);
+ tuklib_mbstr_fw(cols1[0],
+ headings[HEADING_STREAM].columns),
+ cols1[0],
+ tuklib_mbstr_fw(cols1[1],
+ headings[HEADING_BLOCK].columns),
+ cols1[1],
+ tuklib_mbstr_fw(cols1[2],
+ headings[HEADING_COMPOFFSET].columns),
+ cols1[2],
+ tuklib_mbstr_fw(cols1[3], headings[
+ HEADING_UNCOMPOFFSET].columns),
+ cols1[3]);
const char *cols2[4] = {
uint64_to_str(iter.block.total_size, 0),
@@ -778,11 +925,18 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
_(check_names[iter.stream.flags->check])
};
printf("%*s %*s %*s %-*s",
- tuklib_mbstr_fw(cols2[0], 15), cols2[0],
- tuklib_mbstr_fw(cols2[1], 15), cols2[1],
- tuklib_mbstr_fw(cols2[2], 5), cols2[2],
- tuklib_mbstr_fw(cols2[3], detailed ? 11 : 1),
- cols2[3]);
+ tuklib_mbstr_fw(cols2[0],
+ headings[HEADING_TOTALSIZE].columns),
+ cols2[0],
+ tuklib_mbstr_fw(cols2[1],
+ headings[HEADING_UNCOMPSIZE].columns),
+ cols2[1],
+ tuklib_mbstr_fw(cols2[2],
+ headings[HEADING_RATIO].columns),
+ cols2[2],
+ tuklib_mbstr_fw(cols2[3], detailed
+ ? headings[HEADING_CHECK].columns : 1),
+ cols2[3]);
if (detailed) {
const lzma_vli compressed_size
@@ -803,13 +957,20 @@ print_info_adv(xz_file_info *xfi, file_pair *pair)
};
// Show MiB for memory usage, because it
// is the only size which is not in bytes.
- printf("%-*s %*s %-5s %*s %*s MiB %s",
+ printf(" %-*s %*s %-*s %*s %*s MiB %s",
checkval_width, cols3[0],
- tuklib_mbstr_fw(cols3[1], 6), cols3[1],
+ tuklib_mbstr_fw(cols3[1], headings[
+ HEADING_HEADERSIZE].columns),
+ cols3[1],
+ tuklib_mbstr_fw(cols3[2], headings[
+ HEADING_HEADERFLAGS].columns),
cols3[2],
- tuklib_mbstr_fw(cols3[3], 15),
- cols3[3],
- tuklib_mbstr_fw(cols3[4], 7), cols3[4],
+ tuklib_mbstr_fw(cols3[3], headings[
+ HEADING_COMPSIZE].columns),
+ cols3[3],
+ tuklib_mbstr_fw(cols3[4], headings[
+ HEADING_MEMUSAGE].columns - 4),
+ cols3[4],
cols3[5]);
}