| OLD | NEW |
| 1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
| 2 // | 2 // |
| 3 /// \file list.c | 3 /// \file list.c |
| 4 /// \brief Listing information about .xz files | 4 /// \brief Listing information about .xz files |
| 5 // | 5 // |
| 6 // Author: Lasse Collin | 6 // Author: Lasse Collin |
| 7 // | 7 // |
| 8 // This file has been put into the public domain. | 8 // This file has been put into the public domain. |
| 9 // You can do whatever you want with this file. | 9 // You can do whatever you want with this file. |
| 10 // | 10 // |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 /// A few of the Block Flags as a string | 42 /// A few of the Block Flags as a string |
| 43 char flags[3]; | 43 char flags[3]; |
| 44 | 44 |
| 45 /// Size of the Compressed Data field in the Block | 45 /// Size of the Compressed Data field in the Block |
| 46 lzma_vli compressed_size; | 46 lzma_vli compressed_size; |
| 47 | 47 |
| 48 /// Decoder memory usage for this Block | 48 /// Decoder memory usage for this Block |
| 49 uint64_t memusage; | 49 uint64_t memusage; |
| 50 | 50 |
| 51 /// The filter chain of this Block in human-readable form | 51 /// The filter chain of this Block in human-readable form |
| 52 » const char *filter_chain; | 52 » char filter_chain[FILTERS_STR_SIZE]; |
| 53 | 53 |
| 54 } block_header_info; | 54 } block_header_info; |
| 55 | 55 |
| 56 | 56 |
| 57 /// Check ID to string mapping | 57 /// Check ID to string mapping |
| 58 static const char check_names[LZMA_CHECK_ID_MAX + 1][12] = { | 58 static const char check_names[LZMA_CHECK_ID_MAX + 1][12] = { |
| 59 » "None", | 59 » // TRANSLATORS: Indicates that there is no integrity check. |
| 60 » // This string is used in tables, so the width must not |
| 61 » // exceed ten columns with a fixed-width font. |
| 62 » N_("None"), |
| 60 "CRC32", | 63 "CRC32", |
| 61 » "Unknown-2", | 64 » // TRANSLATORS: Indicates that integrity check name is not known, |
| 62 » "Unknown-3", | 65 » // but the Check ID is known (here 2). This and other "Unknown-N" |
| 66 » // strings are used in tables, so the width must not exceed ten |
| 67 » // columns with a fixed-width font. It's OK to omit the dash if |
| 68 » // you need space for one extra letter, but don't use spaces. |
| 69 » N_("Unknown-2"), |
| 70 » N_("Unknown-3"), |
| 63 "CRC64", | 71 "CRC64", |
| 64 » "Unknown-5", | 72 » N_("Unknown-5"), |
| 65 » "Unknown-6", | 73 » N_("Unknown-6"), |
| 66 » "Unknown-7", | 74 » N_("Unknown-7"), |
| 67 » "Unknown-8", | 75 » N_("Unknown-8"), |
| 68 » "Unknown-9", | 76 » N_("Unknown-9"), |
| 69 "SHA-256", | 77 "SHA-256", |
| 70 » "Unknown-11", | 78 » N_("Unknown-11"), |
| 71 » "Unknown-12", | 79 » N_("Unknown-12"), |
| 72 » "Unknown-13", | 80 » N_("Unknown-13"), |
| 73 » "Unknown-14", | 81 » N_("Unknown-14"), |
| 74 » "Unknown-15", | 82 » N_("Unknown-15"), |
| 75 }; | 83 }; |
| 76 | 84 |
| 85 /// Buffer size for get_check_names(). This may be a bit ridiculous, |
| 86 /// but at least it's enough if some language needs many multibyte chars. |
| 87 #define CHECKS_STR_SIZE 1024 |
| 88 |
| 77 | 89 |
| 78 /// Value of the Check field as hexadecimal string. | 90 /// Value of the Check field as hexadecimal string. |
| 79 /// This is set by parse_check_value(). | 91 /// This is set by parse_check_value(). |
| 80 static char check_value[2 * LZMA_CHECK_SIZE_MAX + 1]; | 92 static char check_value[2 * LZMA_CHECK_SIZE_MAX + 1]; |
| 81 | 93 |
| 82 | 94 |
| 83 /// Totals that are displayed if there was more than one file. | 95 /// Totals that are displayed if there was more than one file. |
| 84 /// The "files" counter is also used in print_info_adv() to show | 96 /// The "files" counter is also used in print_info_adv() to show |
| 85 /// the file number. | 97 /// the file number. |
| 86 static struct { | 98 static struct { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) { | 208 if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) { |
| 197 message_error("%s: %s", pair->src_name, | 209 message_error("%s: %s", pair->src_name, |
| 198 message_strm(LZMA_DATA_ERROR)); | 210 message_strm(LZMA_DATA_ERROR)); |
| 199 goto error; | 211 goto error; |
| 200 } | 212 } |
| 201 | 213 |
| 202 // Set pos to the beginning of the Index. | 214 // Set pos to the beginning of the Index. |
| 203 pos -= index_size; | 215 pos -= index_size; |
| 204 | 216 |
| 205 // See how much memory we can use for decoding this Index. | 217 // See how much memory we can use for decoding this Index. |
| 206 » » uint64_t memlimit = hardware_memlimit_get(); | 218 » » uint64_t memlimit = hardware_memlimit_get(MODE_LIST); |
| 207 uint64_t memused = 0; | 219 uint64_t memused = 0; |
| 208 if (combined_index != NULL) { | 220 if (combined_index != NULL) { |
| 209 memused = lzma_index_memused(combined_index); | 221 memused = lzma_index_memused(combined_index); |
| 210 if (memused > memlimit) | 222 if (memused > memlimit) |
| 211 message_bug(); | 223 message_bug(); |
| 212 | 224 |
| 213 memlimit -= memused; | 225 memlimit -= memused; |
| 214 } | 226 } |
| 215 | 227 |
| 216 // Decode the Index. | 228 // Decode the Index. |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 bhi->header_size = block.header_size; | 447 bhi->header_size = block.header_size; |
| 436 bhi->compressed_size = block.compressed_size; | 448 bhi->compressed_size = block.compressed_size; |
| 437 | 449 |
| 438 // Calculate the decoder memory usage and update the maximum | 450 // Calculate the decoder memory usage and update the maximum |
| 439 // memory usage of this Block. | 451 // memory usage of this Block. |
| 440 bhi->memusage = lzma_raw_decoder_memusage(filters); | 452 bhi->memusage = lzma_raw_decoder_memusage(filters); |
| 441 if (xfi->memusage_max < bhi->memusage) | 453 if (xfi->memusage_max < bhi->memusage) |
| 442 xfi->memusage_max = bhi->memusage; | 454 xfi->memusage_max = bhi->memusage; |
| 443 | 455 |
| 444 // Convert the filter chain to human readable form. | 456 // Convert the filter chain to human readable form. |
| 445 » bhi->filter_chain = message_filters_to_str(filters, false); | 457 » message_filters_to_str(bhi->filter_chain, filters, false); |
| 446 | 458 |
| 447 // Free the memory allocated by lzma_block_header_decode(). | 459 // Free the memory allocated by lzma_block_header_decode(). |
| 448 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) | 460 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) |
| 449 free(filters[i].options); | 461 free(filters[i].options); |
| 450 | 462 |
| 451 return false; | 463 return false; |
| 452 | 464 |
| 453 data_error: | 465 data_error: |
| 454 // Show the error message. | 466 // Show the error message. |
| 455 message_error("%s: %s", pair->src_name, | 467 message_error("%s: %s", pair->src_name, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 | 538 |
| 527 if (parse_check_value(pair, iter)) | 539 if (parse_check_value(pair, iter)) |
| 528 return true; | 540 return true; |
| 529 | 541 |
| 530 return false; | 542 return false; |
| 531 } | 543 } |
| 532 | 544 |
| 533 | 545 |
| 534 /// \brief Get the compression ratio | 546 /// \brief Get the compression ratio |
| 535 /// | 547 /// |
| 536 /// This has slightly different format than that is used by in message.c. | 548 /// This has slightly different format than that is used in message.c. |
| 537 static const char * | 549 static const char * |
| 538 get_ratio(uint64_t compressed_size, uint64_t uncompressed_size) | 550 get_ratio(uint64_t compressed_size, uint64_t uncompressed_size) |
| 539 { | 551 { |
| 540 if (uncompressed_size == 0) | 552 if (uncompressed_size == 0) |
| 541 return "---"; | 553 return "---"; |
| 542 | 554 |
| 543 const double ratio = (double)(compressed_size) | 555 const double ratio = (double)(compressed_size) |
| 544 / (double)(uncompressed_size); | 556 / (double)(uncompressed_size); |
| 545 if (ratio > 9.999) | 557 if (ratio > 9.999) |
| 546 return "---"; | 558 return "---"; |
| 547 | 559 |
| 548 » static char buf[6]; | 560 » static char buf[16]; |
| 549 snprintf(buf, sizeof(buf), "%.3f", ratio); | 561 snprintf(buf, sizeof(buf), "%.3f", ratio); |
| 550 return buf; | 562 return buf; |
| 551 } | 563 } |
| 552 | 564 |
| 553 | 565 |
| 554 /// \brief Get a comma-separated list of Check names | 566 /// \brief Get a comma-separated list of Check names |
| 555 /// | 567 /// |
| 568 /// The check names are translated with gettext except when in robot mode. |
| 569 /// |
| 570 /// \param buf Buffer to hold the resulting string |
| 556 /// \param checks Bit mask of Checks to print | 571 /// \param checks Bit mask of Checks to print |
| 557 /// \param space_after_comma | 572 /// \param space_after_comma |
| 558 /// It's better to not use spaces in table-like listings, | 573 /// It's better to not use spaces in table-like listings, |
| 559 /// but in more verbose formats a space after a comma | 574 /// but in more verbose formats a space after a comma |
| 560 /// is good for readability. | 575 /// is good for readability. |
| 561 static const char * | 576 static void |
| 562 get_check_names(uint32_t checks, bool space_after_comma) | 577 get_check_names(char buf[CHECKS_STR_SIZE], |
| 578 » » uint32_t checks, bool space_after_comma) |
| 563 { | 579 { |
| 564 assert(checks != 0); | 580 assert(checks != 0); |
| 565 | 581 |
| 566 static char buf[sizeof(check_names)]; | |
| 567 char *pos = buf; | 582 char *pos = buf; |
| 568 » size_t left = sizeof(buf); | 583 » size_t left = CHECKS_STR_SIZE; |
| 569 | 584 |
| 570 const char *sep = space_after_comma ? ", " : ","; | 585 const char *sep = space_after_comma ? ", " : ","; |
| 571 bool comma = false; | 586 bool comma = false; |
| 572 | 587 |
| 573 for (size_t i = 0; i <= LZMA_CHECK_ID_MAX; ++i) { | 588 for (size_t i = 0; i <= LZMA_CHECK_ID_MAX; ++i) { |
| 574 if (checks & (UINT32_C(1) << i)) { | 589 if (checks & (UINT32_C(1) << i)) { |
| 575 my_snprintf(&pos, &left, "%s%s", | 590 my_snprintf(&pos, &left, "%s%s", |
| 576 » » » » » comma ? sep : "", check_names[i]); | 591 » » » » » comma ? sep : "", |
| 592 » » » » » opt_robot ? check_names[i] |
| 593 » » » » » » : _(check_names[i])); |
| 577 comma = true; | 594 comma = true; |
| 578 } | 595 } |
| 579 } | 596 } |
| 580 | 597 |
| 581 » return buf; | 598 » return; |
| 582 } | 599 } |
| 583 | 600 |
| 584 | 601 |
| 585 static bool | 602 static bool |
| 586 print_info_basic(const xz_file_info *xfi, file_pair *pair) | 603 print_info_basic(const xz_file_info *xfi, file_pair *pair) |
| 587 { | 604 { |
| 588 static bool headings_displayed = false; | 605 static bool headings_displayed = false; |
| 589 if (!headings_displayed) { | 606 if (!headings_displayed) { |
| 590 headings_displayed = true; | 607 headings_displayed = true; |
| 591 » » // TRANSLATORS: These are column titles. From Strms (Streams) | 608 » » // TRANSLATORS: These are column headings. From Strms (Streams) |
| 592 // to Ratio, the columns are right aligned. Check and Filename | 609 // to Ratio, the columns are right aligned. Check and Filename |
| 593 // are left aligned. If you need longer words, it's OK to | 610 // are left aligned. If you need longer words, it's OK to |
| 594 » » // use two lines here. Test with xz --list. | 611 » » // use two lines here. Test with "xz -l foo.xz". |
| 595 puts(_("Strms Blocks Compressed Uncompressed Ratio " | 612 puts(_("Strms Blocks Compressed Uncompressed Ratio " |
| 596 "Check Filename")); | 613 "Check Filename")); |
| 597 } | 614 } |
| 598 | 615 |
| 599 » printf("%5s %7s %11s %11s %5s %-7s %s\n", | 616 » char checks[CHECKS_STR_SIZE]; |
| 600 » » » uint64_to_str(lzma_index_stream_count(xfi->idx), 0), | 617 » get_check_names(checks, lzma_index_checks(xfi->idx), false); |
| 601 » » » uint64_to_str(lzma_index_block_count(xfi->idx), 1), | 618 |
| 602 » » » uint64_to_nicestr(lzma_index_file_size(xfi->idx), | 619 » const char *cols[7] = { |
| 603 » » » » NICESTR_B, NICESTR_TIB, false, 2), | 620 » » uint64_to_str(lzma_index_stream_count(xfi->idx), 0), |
| 604 » » » uint64_to_nicestr( | 621 » » uint64_to_str(lzma_index_block_count(xfi->idx), 1), |
| 605 » » » » lzma_index_uncompressed_size(xfi->idx), | 622 » » uint64_to_nicestr(lzma_index_file_size(xfi->idx), |
| 606 » » » » NICESTR_B, NICESTR_TIB, false, 3), | 623 » » » NICESTR_B, NICESTR_TIB, false, 2), |
| 607 » » » get_ratio(lzma_index_file_size(xfi->idx), | 624 » » uint64_to_nicestr(lzma_index_uncompressed_size(xfi->idx), |
| 608 » » » » lzma_index_uncompressed_size(xfi->idx)), | 625 » » » NICESTR_B, NICESTR_TIB, false, 3), |
| 609 » » » get_check_names(lzma_index_checks(xfi->idx), false), | 626 » » get_ratio(lzma_index_file_size(xfi->idx), |
| 610 » » » pair->src_name); | 627 » » » lzma_index_uncompressed_size(xfi->idx)), |
| 628 » » checks, |
| 629 » » pair->src_name, |
| 630 » }; |
| 631 » printf("%*s %*s %*s %*s %*s %-*s %s\n", |
| 632 » » » tuklib_mbstr_fw(cols[0], 5), cols[0], |
| 633 » » » tuklib_mbstr_fw(cols[1], 7), cols[1], |
| 634 » » » tuklib_mbstr_fw(cols[2], 11), cols[2], |
| 635 » » » tuklib_mbstr_fw(cols[3], 11), cols[3], |
| 636 » » » tuklib_mbstr_fw(cols[4], 5), cols[4], |
| 637 » » » tuklib_mbstr_fw(cols[5], 7), cols[5], |
| 638 » » » cols[6]); |
| 611 | 639 |
| 612 return false; | 640 return false; |
| 613 } | 641 } |
| 614 | 642 |
| 615 | 643 |
| 616 static void | 644 static void |
| 617 print_adv_helper(uint64_t stream_count, uint64_t block_count, | 645 print_adv_helper(uint64_t stream_count, uint64_t block_count, |
| 618 uint64_t compressed_size, uint64_t uncompressed_size, | 646 uint64_t compressed_size, uint64_t uncompressed_size, |
| 619 uint32_t checks, uint64_t stream_padding) | 647 uint32_t checks, uint64_t stream_padding) |
| 620 { | 648 { |
| 649 char checks_str[CHECKS_STR_SIZE]; |
| 650 get_check_names(checks_str, checks, true); |
| 651 |
| 621 printf(_(" Streams: %s\n"), | 652 printf(_(" Streams: %s\n"), |
| 622 uint64_to_str(stream_count, 0)); | 653 uint64_to_str(stream_count, 0)); |
| 623 printf(_(" Blocks: %s\n"), | 654 printf(_(" Blocks: %s\n"), |
| 624 uint64_to_str(block_count, 0)); | 655 uint64_to_str(block_count, 0)); |
| 625 printf(_(" Compressed size: %s\n"), | 656 printf(_(" Compressed size: %s\n"), |
| 626 uint64_to_nicestr(compressed_size, | 657 uint64_to_nicestr(compressed_size, |
| 627 NICESTR_B, NICESTR_TIB, true, 0)); | 658 NICESTR_B, NICESTR_TIB, true, 0)); |
| 628 printf(_(" Uncompressed size: %s\n"), | 659 printf(_(" Uncompressed size: %s\n"), |
| 629 uint64_to_nicestr(uncompressed_size, | 660 uint64_to_nicestr(uncompressed_size, |
| 630 NICESTR_B, NICESTR_TIB, true, 0)); | 661 NICESTR_B, NICESTR_TIB, true, 0)); |
| 631 printf(_(" Ratio: %s\n"), | 662 printf(_(" Ratio: %s\n"), |
| 632 get_ratio(compressed_size, uncompressed_size)); | 663 get_ratio(compressed_size, uncompressed_size)); |
| 633 » printf(_(" Check: %s\n"), | 664 » printf(_(" Check: %s\n"), checks_str); |
| 634 » » » get_check_names(checks, true)); | |
| 635 printf(_(" Stream padding: %s\n"), | 665 printf(_(" Stream padding: %s\n"), |
| 636 uint64_to_nicestr(stream_padding, | 666 uint64_to_nicestr(stream_padding, |
| 637 NICESTR_B, NICESTR_TIB, true, 0)); | 667 NICESTR_B, NICESTR_TIB, true, 0)); |
| 638 return; | 668 return; |
| 639 } | 669 } |
| 640 | 670 |
| 641 | 671 |
| 642 static bool | 672 static bool |
| 643 print_info_adv(xz_file_info *xfi, file_pair *pair) | 673 print_info_adv(xz_file_info *xfi, file_pair *pair) |
| 644 { | 674 { |
| 645 // Print the overall information. | 675 // Print the overall information. |
| 646 print_adv_helper(lzma_index_stream_count(xfi->idx), | 676 print_adv_helper(lzma_index_stream_count(xfi->idx), |
| 647 lzma_index_block_count(xfi->idx), | 677 lzma_index_block_count(xfi->idx), |
| 648 lzma_index_file_size(xfi->idx), | 678 lzma_index_file_size(xfi->idx), |
| 649 lzma_index_uncompressed_size(xfi->idx), | 679 lzma_index_uncompressed_size(xfi->idx), |
| 650 lzma_index_checks(xfi->idx), | 680 lzma_index_checks(xfi->idx), |
| 651 xfi->stream_padding); | 681 xfi->stream_padding); |
| 652 | 682 |
| 653 // Size of the biggest Check. This is used to calculate the width | 683 // Size of the biggest Check. This is used to calculate the width |
| 654 // of the CheckVal field. The table would get insanely wide if | 684 // of the CheckVal field. The table would get insanely wide if |
| 655 // we always reserved space for 64-byte Check (128 chars as hex). | 685 // we always reserved space for 64-byte Check (128 chars as hex). |
| 656 uint32_t check_max = 0; | 686 uint32_t check_max = 0; |
| 657 | 687 |
| 658 // Print information about the Streams. | 688 // Print information about the Streams. |
| 689 // |
| 690 // TRANSLATORS: The second line is column headings. All except |
| 691 // Check are right aligned; Check is left aligned. Test with |
| 692 // "xz -lv foo.xz". |
| 659 puts(_(" Streams:\n Stream Blocks" | 693 puts(_(" Streams:\n Stream Blocks" |
| 660 " CompOffset UncompOffset" | 694 " CompOffset UncompOffset" |
| 661 " CompSize UncompSize Ratio" | 695 " CompSize UncompSize Ratio" |
| 662 " Check Padding")); | 696 " Check Padding")); |
| 663 | 697 |
| 664 lzma_index_iter iter; | 698 lzma_index_iter iter; |
| 665 lzma_index_iter_init(&iter, xfi->idx); | 699 lzma_index_iter_init(&iter, xfi->idx); |
| 666 | 700 |
| 667 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)) { | 701 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)) { |
| 668 » » printf(" %6s %9s %15s %15s ", | 702 » » const char *cols1[4] = { |
| 669 » » » » uint64_to_str(iter.stream.number, 0), | 703 » » » uint64_to_str(iter.stream.number, 0), |
| 670 » » » » uint64_to_str(iter.stream.block_count, 1), | 704 » » » uint64_to_str(iter.stream.block_count, 1), |
| 671 » » » » uint64_to_str( | 705 » » » uint64_to_str(iter.stream.compressed_offset, 2), |
| 672 » » » » » iter.stream.compressed_offset, 2), | 706 » » » uint64_to_str(iter.stream.uncompressed_offset, 3), |
| 673 » » » » uint64_to_str( | 707 » » }; |
| 674 » » » » » iter.stream.uncompressed_offset, 3)); | 708 » » printf(" %*s %*s %*s %*s ", |
| 675 » » printf("%15s %15s %5s %-10s %7s\n", | 709 » » » » tuklib_mbstr_fw(cols1[0], 6), cols1[0], |
| 676 » » » » uint64_to_str(iter.stream.compressed_size, 0), | 710 » » » » tuklib_mbstr_fw(cols1[1], 9), cols1[1], |
| 677 » » » » uint64_to_str( | 711 » » » » tuklib_mbstr_fw(cols1[2], 15), cols1[2], |
| 678 » » » » » iter.stream.uncompressed_size, 1), | 712 » » » » tuklib_mbstr_fw(cols1[3], 15), cols1[3]); |
| 679 » » » » get_ratio(iter.stream.compressed_size, | 713 |
| 680 » » » » » iter.stream.uncompressed_size), | 714 » » const char *cols2[5] = { |
| 681 » » » » check_names[iter.stream.flags->check], | 715 » » » uint64_to_str(iter.stream.compressed_size, 0), |
| 682 » » » » uint64_to_str(iter.stream.padding, 2)); | 716 » » » uint64_to_str(iter.stream.uncompressed_size, 1), |
| 717 » » » get_ratio(iter.stream.compressed_size, |
| 718 » » » » iter.stream.uncompressed_size), |
| 719 » » » _(check_names[iter.stream.flags->check]), |
| 720 » » » uint64_to_str(iter.stream.padding, 2), |
| 721 » » }; |
| 722 » » printf("%*s %*s %*s %-*s %*s\n", |
| 723 » » » » tuklib_mbstr_fw(cols2[0], 15), cols2[0], |
| 724 » » » » tuklib_mbstr_fw(cols2[1], 15), cols2[1], |
| 725 » » » » tuklib_mbstr_fw(cols2[2], 5), cols2[2], |
| 726 » » » » tuklib_mbstr_fw(cols2[3], 10), cols2[3], |
| 727 » » » » tuklib_mbstr_fw(cols2[4], 7), cols2[4]); |
| 683 | 728 |
| 684 // Update the maximum Check size. | 729 // Update the maximum Check size. |
| 685 if (lzma_check_size(iter.stream.flags->check) > check_max) | 730 if (lzma_check_size(iter.stream.flags->check) > check_max) |
| 686 check_max = lzma_check_size(iter.stream.flags->check); | 731 check_max = lzma_check_size(iter.stream.flags->check); |
| 687 } | 732 } |
| 688 | 733 |
| 689 // Cache the verbosity level to a local variable. | 734 // Cache the verbosity level to a local variable. |
| 690 const bool detailed = message_verbosity_get() >= V_DEBUG; | 735 const bool detailed = message_verbosity_get() >= V_DEBUG; |
| 691 | 736 |
| 692 // Information collected from Block Headers | 737 // Information collected from Block Headers |
| 693 block_header_info bhi; | 738 block_header_info bhi; |
| 694 | 739 |
| 695 // Print information about the Blocks but only if there is | 740 // Print information about the Blocks but only if there is |
| 696 // at least one Block. | 741 // at least one Block. |
| 697 if (lzma_index_block_count(xfi->idx) > 0) { | 742 if (lzma_index_block_count(xfi->idx) > 0) { |
| 698 // Calculate the width of the CheckVal field. | 743 // Calculate the width of the CheckVal field. |
| 699 const int checkval_width = my_max(8, 2 * check_max); | 744 const int checkval_width = my_max(8, 2 * check_max); |
| 700 | 745 |
| 701 » » // Print the headings. | 746 » » // TRANSLATORS: The second line is column headings. All |
| 747 » » // except Check are right aligned; Check is left aligned. |
| 702 printf(_(" Blocks:\n Stream Block" | 748 printf(_(" Blocks:\n Stream Block" |
| 703 " CompOffset UncompOffset" | 749 " CompOffset UncompOffset" |
| 704 " TotalSize UncompSize Ratio Check")); | 750 " TotalSize UncompSize Ratio Check")); |
| 705 | 751 |
| 706 » » if (detailed) | 752 » » if (detailed) { |
| 707 » » » printf(_(" %-*s Header Flags CompSize" | 753 » » » // TRANSLATORS: These are additional column headings |
| 708 » » » » » " MemUsage Filters"), | 754 » » » // for the most verbose listing mode. CheckVal |
| 709 » » » » » checkval_width, _("CheckVal")); | 755 » » » // (Check value), Flags, and Filters are left aligned. |
| 756 » » » // Header (Block Header Size), CompSize, and MemUsage |
| 757 » » » // are right aligned. %*s is replaced with 0-120 |
| 758 » » » // spaces to make the CheckVal column wide enough. |
| 759 » » » // Test with "xz -lvv foo.xz". |
| 760 » » » printf(_(" CheckVal %*s Header Flags " |
| 761 » » » » » "CompSize MemUsage Filters"), |
| 762 » » » » » checkval_width - 8, ""); |
| 763 » » } |
| 710 | 764 |
| 711 putchar('\n'); | 765 putchar('\n'); |
| 712 | 766 |
| 713 lzma_index_iter_init(&iter, xfi->idx); | 767 lzma_index_iter_init(&iter, xfi->idx); |
| 714 | 768 |
| 715 // Iterate over the Blocks. | 769 // Iterate over the Blocks. |
| 716 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) { | 770 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) { |
| 717 if (detailed && parse_details(pair, &iter, &bhi, xfi)) | 771 if (detailed && parse_details(pair, &iter, &bhi, xfi)) |
| 718 return true; | 772 return true; |
| 719 | 773 |
| 720 » » » printf(" %6s %9s %15s %15s ", | 774 » » » const char *cols1[4] = { |
| 721 uint64_to_str(iter.stream.number, 0), | 775 uint64_to_str(iter.stream.number, 0), |
| 722 uint64_to_str( | 776 uint64_to_str( |
| 723 iter.block.number_in_stream, 1), | 777 iter.block.number_in_stream, 1), |
| 724 uint64_to_str( | 778 uint64_to_str( |
| 725 iter.block.compressed_file_offset, 2), | 779 iter.block.compressed_file_offset, 2), |
| 726 uint64_to_str( | 780 uint64_to_str( |
| 727 » » » » » iter.block.uncompressed_file_offset, | 781 » » » » » iter.block.uncompressed_file_offset, 3) |
| 728 » » » » » 3)); | 782 » » » }; |
| 729 » » » printf("%15s %15s %5s %-*s", | 783 » » » printf(" %*s %*s %*s %*s ", |
| 784 » » » » tuklib_mbstr_fw(cols1[0], 6), cols1[0], |
| 785 » » » » tuklib_mbstr_fw(cols1[1], 9), cols1[1], |
| 786 » » » » tuklib_mbstr_fw(cols1[2], 15), cols1[2], |
| 787 » » » » tuklib_mbstr_fw(cols1[3], 15), cols1[3]); |
| 788 |
| 789 » » » const char *cols2[4] = { |
| 730 uint64_to_str(iter.block.total_size, 0), | 790 uint64_to_str(iter.block.total_size, 0), |
| 731 uint64_to_str(iter.block.uncompressed_size, | 791 uint64_to_str(iter.block.uncompressed_size, |
| 732 1), | 792 1), |
| 733 get_ratio(iter.block.total_size, | 793 get_ratio(iter.block.total_size, |
| 734 iter.block.uncompressed_size), | 794 iter.block.uncompressed_size), |
| 735 » » » » detailed ? 11 : 1, | 795 » » » » _(check_names[iter.stream.flags->check]) |
| 736 » » » » check_names[iter.stream.flags->check]); | 796 » » » }; |
| 797 » » » printf("%*s %*s %*s %-*s", |
| 798 » » » » tuklib_mbstr_fw(cols2[0], 15), cols2[0], |
| 799 » » » » tuklib_mbstr_fw(cols2[1], 15), cols2[1], |
| 800 » » » » tuklib_mbstr_fw(cols2[2], 5), cols2[2], |
| 801 » » » » tuklib_mbstr_fw(cols2[3], detailed ? 11 : 1), |
| 802 » » » » » cols2[3]); |
| 737 | 803 |
| 738 if (detailed) { | 804 if (detailed) { |
| 739 // Show MiB for memory usage, because it | |
| 740 // is the only size which is not in bytes. | |
| 741 const lzma_vli compressed_size | 805 const lzma_vli compressed_size |
| 742 = iter.block.unpadded_size | 806 = iter.block.unpadded_size |
| 743 - bhi.header_size | 807 - bhi.header_size |
| 744 - lzma_check_size( | 808 - lzma_check_size( |
| 745 iter.stream.flags->check); | 809 iter.stream.flags->check); |
| 746 » » » » printf("%-*s %6s %-5s %15s %7s MiB %s", | 810 |
| 747 » » » » » checkval_width, check_value, | 811 » » » » const char *cols3[6] = { |
| 812 » » » » » check_value, |
| 748 uint64_to_str(bhi.header_size, 0), | 813 uint64_to_str(bhi.header_size, 0), |
| 749 bhi.flags, | 814 bhi.flags, |
| 750 uint64_to_str(compressed_size, 1), | 815 uint64_to_str(compressed_size, 1), |
| 751 uint64_to_str( | 816 uint64_to_str( |
| 752 round_up_to_mib(bhi.memusage), | 817 round_up_to_mib(bhi.memusage), |
| 753 2), | 818 2), |
| 754 » » » » » bhi.filter_chain); | 819 » » » » » bhi.filter_chain |
| 820 » » » » }; |
| 821 » » » » // Show MiB for memory usage, because it |
| 822 » » » » // is the only size which is not in bytes. |
| 823 » » » » printf("%-*s %*s %-5s %*s %*s MiB %s", |
| 824 » » » » » checkval_width, cols3[0], |
| 825 » » » » » tuklib_mbstr_fw(cols3[1], 6), cols3[1], |
| 826 » » » » » cols3[2], |
| 827 » » » » » tuklib_mbstr_fw(cols3[3], 15), |
| 828 » » » » » » cols3[3], |
| 829 » » » » » tuklib_mbstr_fw(cols3[4], 7), cols3[4], |
| 830 » » » » » cols3[5]); |
| 755 } | 831 } |
| 756 | 832 |
| 757 putchar('\n'); | 833 putchar('\n'); |
| 758 } | 834 } |
| 759 } | 835 } |
| 760 | 836 |
| 761 if (detailed) { | 837 if (detailed) { |
| 762 printf(_(" Memory needed: %s MiB\n"), uint64_to_str( | 838 printf(_(" Memory needed: %s MiB\n"), uint64_to_str( |
| 763 round_up_to_mib(xfi->memusage_max), 0)); | 839 round_up_to_mib(xfi->memusage_max), 0)); |
| 764 printf(_(" Sizes in headers: %s\n"), | 840 printf(_(" Sizes in headers: %s\n"), |
| 765 xfi->all_have_sizes ? _("Yes") : _("No")); | 841 xfi->all_have_sizes ? _("Yes") : _("No")); |
| 766 } | 842 } |
| 767 | 843 |
| 768 return false; | 844 return false; |
| 769 } | 845 } |
| 770 | 846 |
| 771 | 847 |
| 772 static bool | 848 static bool |
| 773 print_info_robot(xz_file_info *xfi, file_pair *pair) | 849 print_info_robot(xz_file_info *xfi, file_pair *pair) |
| 774 { | 850 { |
| 851 char checks[CHECKS_STR_SIZE]; |
| 852 get_check_names(checks, lzma_index_checks(xfi->idx), false); |
| 853 |
| 775 printf("name\t%s\n", pair->src_name); | 854 printf("name\t%s\n", pair->src_name); |
| 776 | 855 |
| 777 printf("file\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 | 856 printf("file\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 |
| 778 "\t%s\t%s\t%" PRIu64 "\n", | 857 "\t%s\t%s\t%" PRIu64 "\n", |
| 779 lzma_index_stream_count(xfi->idx), | 858 lzma_index_stream_count(xfi->idx), |
| 780 lzma_index_block_count(xfi->idx), | 859 lzma_index_block_count(xfi->idx), |
| 781 lzma_index_file_size(xfi->idx), | 860 lzma_index_file_size(xfi->idx), |
| 782 lzma_index_uncompressed_size(xfi->idx), | 861 lzma_index_uncompressed_size(xfi->idx), |
| 783 get_ratio(lzma_index_file_size(xfi->idx), | 862 get_ratio(lzma_index_file_size(xfi->idx), |
| 784 lzma_index_uncompressed_size(xfi->idx)), | 863 lzma_index_uncompressed_size(xfi->idx)), |
| 785 » » » get_check_names(lzma_index_checks(xfi->idx), false), | 864 » » » checks, |
| 786 xfi->stream_padding); | 865 xfi->stream_padding); |
| 787 | 866 |
| 788 if (message_verbosity_get() >= V_VERBOSE) { | 867 if (message_verbosity_get() >= V_VERBOSE) { |
| 789 lzma_index_iter iter; | 868 lzma_index_iter iter; |
| 790 lzma_index_iter_init(&iter, xfi->idx); | 869 lzma_index_iter_init(&iter, xfi->idx); |
| 791 | 870 |
| 792 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)) | 871 while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)) |
| 793 printf("stream\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 | 872 printf("stream\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 |
| 794 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 | 873 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 |
| 795 "\t%s\t%s\t%" PRIu64 "\n", | 874 "\t%s\t%s\t%" PRIu64 "\n", |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 | 952 |
| 874 static void | 953 static void |
| 875 print_totals_basic(void) | 954 print_totals_basic(void) |
| 876 { | 955 { |
| 877 // Print a separator line. | 956 // Print a separator line. |
| 878 char line[80]; | 957 char line[80]; |
| 879 memset(line, '-', sizeof(line)); | 958 memset(line, '-', sizeof(line)); |
| 880 line[sizeof(line) - 1] = '\0'; | 959 line[sizeof(line) - 1] = '\0'; |
| 881 puts(line); | 960 puts(line); |
| 882 | 961 |
| 962 // Get the check names. |
| 963 char checks[CHECKS_STR_SIZE]; |
| 964 get_check_names(checks, totals.checks, false); |
| 965 |
| 883 // Print the totals except the file count, which needs | 966 // Print the totals except the file count, which needs |
| 884 // special handling. | 967 // special handling. |
| 885 printf("%5s %7s %11s %11s %5s %-7s ", | 968 printf("%5s %7s %11s %11s %5s %-7s ", |
| 886 uint64_to_str(totals.streams, 0), | 969 uint64_to_str(totals.streams, 0), |
| 887 uint64_to_str(totals.blocks, 1), | 970 uint64_to_str(totals.blocks, 1), |
| 888 uint64_to_nicestr(totals.compressed_size, | 971 uint64_to_nicestr(totals.compressed_size, |
| 889 NICESTR_B, NICESTR_TIB, false, 2), | 972 NICESTR_B, NICESTR_TIB, false, 2), |
| 890 uint64_to_nicestr(totals.uncompressed_size, | 973 uint64_to_nicestr(totals.uncompressed_size, |
| 891 NICESTR_B, NICESTR_TIB, false, 3), | 974 NICESTR_B, NICESTR_TIB, false, 3), |
| 892 get_ratio(totals.compressed_size, | 975 get_ratio(totals.compressed_size, |
| 893 totals.uncompressed_size), | 976 totals.uncompressed_size), |
| 894 » » » get_check_names(totals.checks, false)); | 977 » » » checks); |
| 895 | 978 |
| 896 // Since we print totals only when there are at least two files, | 979 // Since we print totals only when there are at least two files, |
| 897 // the English message will always use "%s files". But some other | 980 // the English message will always use "%s files". But some other |
| 898 // languages need different forms for different plurals so we | 981 // languages need different forms for different plurals so we |
| 899 » // have to translate this string still. | 982 » // have to translate this with ngettext(). |
| 900 // | 983 // |
| 901 » // TRANSLATORS: This simply indicates the number of files shown | 984 » // TRANSLATORS: %s is an integer. Only the plural form of this |
| 902 » // by --list even though the format string uses %s. | 985 » // message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz". |
| 903 » printf(N_("%s file", "%s files\n", | 986 » printf(ngettext("%s file\n", "%s files\n", |
| 904 totals.files <= ULONG_MAX ? totals.files | 987 totals.files <= ULONG_MAX ? totals.files |
| 905 : (totals.files % 1000000) + 1000000), | 988 : (totals.files % 1000000) + 1000000), |
| 906 uint64_to_str(totals.files, 0)); | 989 uint64_to_str(totals.files, 0)); |
| 907 | 990 |
| 908 return; | 991 return; |
| 909 } | 992 } |
| 910 | 993 |
| 911 | 994 |
| 912 static void | 995 static void |
| 913 print_totals_adv(void) | 996 print_totals_adv(void) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 927 totals.all_have_sizes ? _("Yes") : _("No")); | 1010 totals.all_have_sizes ? _("Yes") : _("No")); |
| 928 } | 1011 } |
| 929 | 1012 |
| 930 return; | 1013 return; |
| 931 } | 1014 } |
| 932 | 1015 |
| 933 | 1016 |
| 934 static void | 1017 static void |
| 935 print_totals_robot(void) | 1018 print_totals_robot(void) |
| 936 { | 1019 { |
| 1020 char checks[CHECKS_STR_SIZE]; |
| 1021 get_check_names(checks, totals.checks, false); |
| 1022 |
| 937 printf("totals\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 | 1023 printf("totals\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 |
| 938 "\t%s\t%s\t%" PRIu64 "\t%" PRIu64, | 1024 "\t%s\t%s\t%" PRIu64 "\t%" PRIu64, |
| 939 totals.streams, | 1025 totals.streams, |
| 940 totals.blocks, | 1026 totals.blocks, |
| 941 totals.compressed_size, | 1027 totals.compressed_size, |
| 942 totals.uncompressed_size, | 1028 totals.uncompressed_size, |
| 943 get_ratio(totals.compressed_size, | 1029 get_ratio(totals.compressed_size, |
| 944 totals.uncompressed_size), | 1030 totals.uncompressed_size), |
| 945 » » » get_check_names(totals.checks, false), | 1031 » » » checks, |
| 946 totals.stream_padding, | 1032 totals.stream_padding, |
| 947 totals.files); | 1033 totals.files); |
| 948 | 1034 |
| 949 if (message_verbosity_get() >= V_DEBUG) | 1035 if (message_verbosity_get() >= V_DEBUG) |
| 950 printf("\t%" PRIu64 "\t%s", | 1036 printf("\t%" PRIu64 "\t%s", |
| 951 totals.memusage_max, | 1037 totals.memusage_max, |
| 952 totals.all_have_sizes ? "yes" : "no"); | 1038 totals.all_have_sizes ? "yes" : "no"); |
| 953 | 1039 |
| 954 putchar('\n'); | 1040 putchar('\n'); |
| 955 | 1041 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 // broken files. | 1109 // broken files. |
| 1024 if (!fail) | 1110 if (!fail) |
| 1025 update_totals(&xfi); | 1111 update_totals(&xfi); |
| 1026 | 1112 |
| 1027 lzma_index_end(xfi.idx, NULL); | 1113 lzma_index_end(xfi.idx, NULL); |
| 1028 } | 1114 } |
| 1029 | 1115 |
| 1030 io_close(pair, false); | 1116 io_close(pair, false); |
| 1031 return; | 1117 return; |
| 1032 } | 1118 } |
| OLD | NEW |