OLD | NEW |
1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 /// \file message.c | 3 /// \file message.c |
4 /// \brief Printing messages | 4 /// \brief Printing messages |
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 | 70 |
71 // Use alarm() and SIGALRM when they are supported. This has two minor | 71 // Use alarm() and SIGALRM when they are supported. This has two minor |
72 // advantages over the alternative of polling gettimeofday(): | 72 // advantages over the alternative of polling gettimeofday(): |
73 // - It is possible for the user to send SIGINFO, SIGUSR1, or SIGALRM to | 73 // - It is possible for the user to send SIGINFO, SIGUSR1, or SIGALRM to |
74 // get intermediate progress information even when --verbose wasn't used | 74 // get intermediate progress information even when --verbose wasn't used |
75 // or stderr is not a terminal. | 75 // or stderr is not a terminal. |
76 // - alarm() + SIGALRM seems to have slightly less overhead than polling | 76 // - alarm() + SIGALRM seems to have slightly less overhead than polling |
77 // gettimeofday(). | 77 // gettimeofday(). |
78 #ifdef SIGALRM | 78 #ifdef SIGALRM |
79 | 79 |
| 80 const int message_progress_sigs[] = { |
| 81 SIGALRM, |
| 82 #ifdef SIGINFO |
| 83 SIGINFO, |
| 84 #endif |
| 85 #ifdef SIGUSR1 |
| 86 SIGUSR1, |
| 87 #endif |
| 88 0 |
| 89 }; |
| 90 |
80 /// The signal handler for SIGALRM sets this to true. It is set back to false | 91 /// The signal handler for SIGALRM sets this to true. It is set back to false |
81 /// once the progress message has been updated. | 92 /// once the progress message has been updated. |
82 static volatile sig_atomic_t progress_needs_updating = false; | 93 static volatile sig_atomic_t progress_needs_updating = false; |
83 | 94 |
84 /// Signal handler for SIGALRM | 95 /// Signal handler for SIGALRM |
85 static void | 96 static void |
86 progress_signal_handler(int sig lzma_attribute((unused))) | 97 progress_signal_handler(int sig lzma_attribute((__unused__))) |
87 { | 98 { |
88 progress_needs_updating = true; | 99 progress_needs_updating = true; |
89 return; | 100 return; |
90 } | 101 } |
91 | 102 |
92 #else | 103 #else |
93 | 104 |
94 /// This is true when progress message printing is wanted. Using the same | 105 /// This is true when progress message printing is wanted. Using the same |
95 /// variable name as above to avoid some ifdefs. | 106 /// variable name as above to avoid some ifdefs. |
96 static bool progress_needs_updating = false; | 107 static bool progress_needs_updating = false; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 if (columns_str != NULL) { | 146 if (columns_str != NULL) { |
136 char *endptr; | 147 char *endptr; |
137 const long columns = strtol(columns_str, &endptr, 10); | 148 const long columns = strtol(columns_str, &endptr, 10); |
138 if (*endptr != '\0' || columns < 80) | 149 if (*endptr != '\0' || columns < 80) |
139 progress_automatic = false; | 150 progress_automatic = false; |
140 } | 151 } |
141 } | 152 } |
142 */ | 153 */ |
143 | 154 |
144 #ifdef SIGALRM | 155 #ifdef SIGALRM |
145 // DJGPP lacks SA_RESTART, but it shouldn't give EINTR | |
146 // in most places either. | |
147 # if defined(__DJGPP__) && !defined(SA_RESTART) | |
148 # define SA_RESTART 0 | |
149 # endif | |
150 | |
151 // Establish the signal handlers which set a flag to tell us that | 156 // Establish the signal handlers which set a flag to tell us that |
152 » // progress info should be updated. Since these signals don't | 157 » // progress info should be updated. |
153 » // require any quick action, we set SA_RESTART. That way we don't | |
154 » // need to block them either in signals_block() to keep stdio | |
155 » // functions from getting EINTR. | |
156 » static const int sigs[] = { | |
157 » » SIGALRM, | |
158 #ifdef SIGINFO | |
159 » » SIGINFO, | |
160 #endif | |
161 #ifdef SIGUSR1 | |
162 » » SIGUSR1, | |
163 #endif | |
164 » }; | |
165 | |
166 struct sigaction sa; | 158 struct sigaction sa; |
167 sigemptyset(&sa.sa_mask); | 159 sigemptyset(&sa.sa_mask); |
168 » sa.sa_flags = SA_RESTART; | 160 » sa.sa_flags = 0; |
169 sa.sa_handler = &progress_signal_handler; | 161 sa.sa_handler = &progress_signal_handler; |
170 | 162 |
171 » for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i) | 163 » for (size_t i = 0; message_progress_sigs[i] != 0; ++i) |
172 » » if (sigaction(sigs[i], &sa, NULL)) | 164 » » if (sigaction(message_progress_sigs[i], &sa, NULL)) |
173 message_signal_handler(); | 165 message_signal_handler(); |
174 #endif | 166 #endif |
175 | 167 |
176 return; | 168 return; |
177 } | 169 } |
178 | 170 |
179 | 171 |
180 extern void | 172 extern void |
181 message_verbosity_increase(void) | 173 message_verbosity_increase(void) |
182 { | 174 { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // clearly wrong since we have processed more data than the alleged | 306 // clearly wrong since we have processed more data than the alleged |
315 // size of the file, show a static string indicating that we have | 307 // size of the file, show a static string indicating that we have |
316 // no idea of the completion percentage. | 308 // no idea of the completion percentage. |
317 if (expected_in_size == 0 || in_pos > expected_in_size) | 309 if (expected_in_size == 0 || in_pos > expected_in_size) |
318 return "--- %"; | 310 return "--- %"; |
319 | 311 |
320 // Never show 100.0 % before we actually are finished. | 312 // Never show 100.0 % before we actually are finished. |
321 double percentage = (double)(in_pos) / (double)(expected_in_size) | 313 double percentage = (double)(in_pos) / (double)(expected_in_size) |
322 * 99.9; | 314 * 99.9; |
323 | 315 |
324 » static char buf[sizeof("99.9 %")]; | 316 » // Use big enough buffer to hold e.g. a multibyte decimal point. |
| 317 » static char buf[16]; |
325 snprintf(buf, sizeof(buf), "%.1f %%", percentage); | 318 snprintf(buf, sizeof(buf), "%.1f %%", percentage); |
326 | 319 |
327 return buf; | 320 return buf; |
328 } | 321 } |
329 | 322 |
330 | 323 |
331 /// Make the string containing the amount of input processed, amount of | 324 /// Make the string containing the amount of input processed, amount of |
332 /// output produced, and the compression ratio. | 325 /// output produced, and the compression ratio. |
333 static const char * | 326 static const char * |
334 progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final) | 327 progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final) |
335 { | 328 { |
336 » // This is enough to hold sizes up to about 99 TiB if thousand | 329 » // Use big enough buffer to hold e.g. a multibyte thousand separators. |
337 » // separator is used, or about 1 PiB without thousand separator. | 330 » static char buf[128]; |
338 » // After that the progress indicator will look a bit silly, since | |
339 » // the compression ratio no longer fits with three decimal places. | |
340 » static char buf[36]; | |
341 | |
342 char *pos = buf; | 331 char *pos = buf; |
343 size_t left = sizeof(buf); | 332 size_t left = sizeof(buf); |
344 | 333 |
345 // Print the sizes. If this the final message, use more reasonable | 334 // Print the sizes. If this the final message, use more reasonable |
346 // units than MiB if the file was small. | 335 // units than MiB if the file was small. |
347 const enum nicestr_unit unit_min = final ? NICESTR_B : NICESTR_MIB; | 336 const enum nicestr_unit unit_min = final ? NICESTR_B : NICESTR_MIB; |
348 my_snprintf(&pos, &left, "%s / %s", | 337 my_snprintf(&pos, &left, "%s / %s", |
349 uint64_to_nicestr(compressed_pos, | 338 uint64_to_nicestr(compressed_pos, |
350 unit_min, NICESTR_TIB, false, 0), | 339 unit_min, NICESTR_TIB, false, 0), |
351 uint64_to_nicestr(uncompressed_pos, | 340 uint64_to_nicestr(uncompressed_pos, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 speed /= 1024.0; | 384 speed /= 1024.0; |
396 if (++unit_index == ARRAY_SIZE(unit)) | 385 if (++unit_index == ARRAY_SIZE(unit)) |
397 return ""; // Way too fast ;-) | 386 return ""; // Way too fast ;-) |
398 } | 387 } |
399 | 388 |
400 // Use decimal point only if the number is small. Examples: | 389 // Use decimal point only if the number is small. Examples: |
401 // - 0.1 KiB/s | 390 // - 0.1 KiB/s |
402 // - 9.9 KiB/s | 391 // - 9.9 KiB/s |
403 // - 99 KiB/s | 392 // - 99 KiB/s |
404 // - 999 KiB/s | 393 // - 999 KiB/s |
405 » static char buf[sizeof("999 GiB/s")]; | 394 » // Use big enough buffer to hold e.g. a multibyte decimal point. |
| 395 » static char buf[16]; |
406 snprintf(buf, sizeof(buf), "%.*f %s", | 396 snprintf(buf, sizeof(buf), "%.*f %s", |
407 speed > 9.9 ? 0 : 1, speed, unit[unit_index]); | 397 speed > 9.9 ? 0 : 1, speed, unit[unit_index]); |
408 return buf; | 398 return buf; |
409 } | 399 } |
410 | 400 |
411 | 401 |
412 /// Make a string indicating elapsed or remaining time. The format is either | 402 /// Make a string indicating elapsed or remaining time. The format is either |
413 /// M:SS or H:MM:SS depending on if the time is an hour or more. | 403 /// M:SS or H:MM:SS depending on if the time is an hour or more. |
414 static const char * | 404 static const char * |
415 progress_time(uint64_t useconds) | 405 progress_time(uint64_t useconds) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // Block signals so that fprintf() doesn't get interrupted. | 571 // Block signals so that fprintf() doesn't get interrupted. |
582 signals_block(); | 572 signals_block(); |
583 | 573 |
584 // Print the filename if it hasn't been printed yet. | 574 // Print the filename if it hasn't been printed yet. |
585 if (!current_filename_printed) | 575 if (!current_filename_printed) |
586 print_filename(); | 576 print_filename(); |
587 | 577 |
588 // Print the actual progress message. The idea is that there is at | 578 // Print the actual progress message. The idea is that there is at |
589 // least three spaces between the fields in typical situations, but | 579 // least three spaces between the fields in typical situations, but |
590 // even in rare situations there is at least one space. | 580 // even in rare situations there is at least one space. |
591 » fprintf(stderr, "\r %6s %35s %9s %10s %10s\r", | 581 » const char *cols[5] = { |
592 progress_percentage(in_pos), | 582 progress_percentage(in_pos), |
593 progress_sizes(compressed_pos, uncompressed_pos, false), | 583 progress_sizes(compressed_pos, uncompressed_pos, false), |
594 progress_speed(uncompressed_pos, elapsed), | 584 progress_speed(uncompressed_pos, elapsed), |
595 progress_time(elapsed), | 585 progress_time(elapsed), |
596 » » progress_remaining(in_pos, elapsed)); | 586 » » progress_remaining(in_pos, elapsed), |
| 587 » }; |
| 588 » fprintf(stderr, "\r %*s %*s %*s %10s %10s\r", |
| 589 » » » tuklib_mbstr_fw(cols[0], 6), cols[0], |
| 590 » » » tuklib_mbstr_fw(cols[1], 35), cols[1], |
| 591 » » » tuklib_mbstr_fw(cols[2], 9), cols[2], |
| 592 » » » cols[3], |
| 593 » » » cols[4]); |
597 | 594 |
598 #ifdef SIGALRM | 595 #ifdef SIGALRM |
599 // Updating the progress info was finished. Reset | 596 // Updating the progress info was finished. Reset |
600 // progress_needs_updating to wait for the next SIGALRM. | 597 // progress_needs_updating to wait for the next SIGALRM. |
601 // | 598 // |
602 // NOTE: This has to be done before alarm(1) or with (very) bad | 599 // NOTE: This has to be done before alarm(1) or with (very) bad |
603 // luck we could be setting this to false after the alarm has already | 600 // luck we could be setting this to false after the alarm has already |
604 // been triggered. | 601 // been triggered. |
605 progress_needs_updating = false; | 602 progress_needs_updating = false; |
606 | 603 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 progress_active = false; | 653 progress_active = false; |
657 | 654 |
658 const uint64_t elapsed = progress_elapsed(); | 655 const uint64_t elapsed = progress_elapsed(); |
659 | 656 |
660 signals_block(); | 657 signals_block(); |
661 | 658 |
662 // When using the auto-updating progress indicator, the final | 659 // When using the auto-updating progress indicator, the final |
663 // statistics are printed in the same format as the progress | 660 // statistics are printed in the same format as the progress |
664 // indicator itself. | 661 // indicator itself. |
665 if (progress_automatic) { | 662 if (progress_automatic) { |
666 » » fprintf(stderr, "\r %6s %35s %9s %10s %10s\n", | 663 » » const char *cols[5] = { |
667 finished ? "100 %" : progress_percentage(in_pos), | 664 finished ? "100 %" : progress_percentage(in_pos), |
668 progress_sizes(compressed_pos, uncompressed_pos, true), | 665 progress_sizes(compressed_pos, uncompressed_pos, true), |
669 progress_speed(uncompressed_pos, elapsed), | 666 progress_speed(uncompressed_pos, elapsed), |
670 progress_time(elapsed), | 667 progress_time(elapsed), |
671 » » » finished ? "" : progress_remaining(in_pos, elapsed)); | 668 » » » finished ? "" : progress_remaining(in_pos, elapsed), |
| 669 » » }; |
| 670 » » fprintf(stderr, "\r %*s %*s %*s %10s %10s\n", |
| 671 » » » » tuklib_mbstr_fw(cols[0], 6), cols[0], |
| 672 » » » » tuklib_mbstr_fw(cols[1], 35), cols[1], |
| 673 » » » » tuklib_mbstr_fw(cols[2], 9), cols[2], |
| 674 » » » » cols[3], |
| 675 » » » » cols[4]); |
672 } else { | 676 } else { |
673 // The filename is always printed. | 677 // The filename is always printed. |
674 fprintf(stderr, "%s: ", filename); | 678 fprintf(stderr, "%s: ", filename); |
675 | 679 |
676 // Percentage is printed only if we didn't finish yet. | 680 // Percentage is printed only if we didn't finish yet. |
677 if (!finished) { | 681 if (!finished) { |
678 // Don't print the percentage when it isn't known | 682 // Don't print the percentage when it isn't known |
679 // (starts with a dash). | 683 // (starts with a dash). |
680 const char *percentage = progress_percentage(in_pos); | 684 const char *percentage = progress_percentage(in_pos); |
681 if (percentage[0] != '-') | 685 if (percentage[0] != '-') |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 | 719 |
716 | 720 |
717 static void | 721 static void |
718 vmessage(enum message_verbosity v, const char *fmt, va_list ap) | 722 vmessage(enum message_verbosity v, const char *fmt, va_list ap) |
719 { | 723 { |
720 if (v <= verbosity) { | 724 if (v <= verbosity) { |
721 signals_block(); | 725 signals_block(); |
722 | 726 |
723 progress_flush(false); | 727 progress_flush(false); |
724 | 728 |
725 » » fprintf(stderr, "%s: ", progname); | 729 » » // TRANSLATORS: This is the program name in the beginning |
| 730 » » // of the line in messages. Usually it becomes "xz: ". |
| 731 » » // This is a translatable string because French needs |
| 732 » » // a space before a colon. |
| 733 » » fprintf(stderr, _("%s: "), progname); |
726 vfprintf(stderr, fmt, ap); | 734 vfprintf(stderr, fmt, ap); |
727 fputc('\n', stderr); | 735 fputc('\n', stderr); |
728 | 736 |
729 signals_unblock(); | 737 signals_unblock(); |
730 } | 738 } |
731 | 739 |
732 return; | 740 return; |
733 } | 741 } |
734 | 742 |
735 | 743 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 case LZMA_DATA_ERROR: | 830 case LZMA_DATA_ERROR: |
823 return _("Compressed data is corrupt"); | 831 return _("Compressed data is corrupt"); |
824 | 832 |
825 case LZMA_BUF_ERROR: | 833 case LZMA_BUF_ERROR: |
826 return _("Unexpected end of input"); | 834 return _("Unexpected end of input"); |
827 | 835 |
828 case LZMA_OK: | 836 case LZMA_OK: |
829 case LZMA_STREAM_END: | 837 case LZMA_STREAM_END: |
830 case LZMA_GET_CHECK: | 838 case LZMA_GET_CHECK: |
831 case LZMA_PROG_ERROR: | 839 case LZMA_PROG_ERROR: |
832 » » return _("Internal error (bug)"); | 840 » » // Without "default", compiler will warn if new constants |
| 841 » » // are added to lzma_ret, it is not too easy to forget to |
| 842 » » // add the new constants to this function. |
| 843 » » break; |
833 } | 844 } |
834 | 845 |
835 » return NULL; | 846 » return _("Internal error (bug)"); |
836 } | 847 } |
837 | 848 |
838 | 849 |
839 extern void | 850 extern void |
840 message_mem_needed(enum message_verbosity v, uint64_t memusage) | 851 message_mem_needed(enum message_verbosity v, uint64_t memusage) |
841 { | 852 { |
842 if (v > verbosity) | 853 if (v > verbosity) |
843 return; | 854 return; |
844 | 855 |
845 // Convert memusage to MiB, rounding up to the next full MiB. | 856 // Convert memusage to MiB, rounding up to the next full MiB. |
846 // This way the user can always use the displayed usage as | 857 // This way the user can always use the displayed usage as |
847 // the new memory usage limit. (If we rounded to the nearest, | 858 // the new memory usage limit. (If we rounded to the nearest, |
848 // the user might need to +1 MiB to get high enough limit.) | 859 // the user might need to +1 MiB to get high enough limit.) |
849 memusage = round_up_to_mib(memusage); | 860 memusage = round_up_to_mib(memusage); |
850 | 861 |
| 862 // With US-ASCII: |
851 // 2^64 with thousand separators + " MiB" suffix + '\0' = 26 + 4 + 1 | 863 // 2^64 with thousand separators + " MiB" suffix + '\0' = 26 + 4 + 1 |
852 » char memlimitstr[32]; | 864 » // But there may be multibyte chars so reserve enough space. |
| 865 » char memlimitstr[128]; |
853 | 866 |
854 // Show the memory usage limit as MiB unless it is less than 1 MiB. | 867 // Show the memory usage limit as MiB unless it is less than 1 MiB. |
855 // This way it's easy to notice errors where one has typed | 868 // This way it's easy to notice errors where one has typed |
856 // --memory=123 instead of --memory=123MiB. | 869 // --memory=123 instead of --memory=123MiB. |
857 » uint64_t memlimit = hardware_memlimit_get(); | 870 » uint64_t memlimit = hardware_memlimit_get(opt_mode); |
858 if (memlimit < (UINT32_C(1) << 20)) { | 871 if (memlimit < (UINT32_C(1) << 20)) { |
859 snprintf(memlimitstr, sizeof(memlimitstr), "%s B", | 872 snprintf(memlimitstr, sizeof(memlimitstr), "%s B", |
860 uint64_to_str(memlimit, 1)); | 873 uint64_to_str(memlimit, 1)); |
861 } else { | 874 } else { |
862 // Round up just like with memusage. If this function is | 875 // Round up just like with memusage. If this function is |
863 // called for informational purposes (to just show the | 876 // called for informational purposes (to just show the |
864 // current usage and limit), we should never show that | 877 // current usage and limit), we should never show that |
865 // the usage is higher than the limit, which would give | 878 // the usage is higher than the limit, which would give |
866 // a false impression that the memory usage limit isn't | 879 // a false impression that the memory usage limit isn't |
867 // properly enforced. | 880 // properly enforced. |
(...skipping 20 matching lines...) Expand all Loading... |
888 snprintf(buf, sizeof(buf), "%" PRIu32 "MiB", num >> 20); | 901 snprintf(buf, sizeof(buf), "%" PRIu32 "MiB", num >> 20); |
889 else if ((num & ((UINT32_C(1) << 10) - 1)) == 0) | 902 else if ((num & ((UINT32_C(1) << 10) - 1)) == 0) |
890 snprintf(buf, sizeof(buf), "%" PRIu32 "KiB", num >> 10); | 903 snprintf(buf, sizeof(buf), "%" PRIu32 "KiB", num >> 10); |
891 else | 904 else |
892 snprintf(buf, sizeof(buf), "%" PRIu32, num); | 905 snprintf(buf, sizeof(buf), "%" PRIu32, num); |
893 | 906 |
894 return buf; | 907 return buf; |
895 } | 908 } |
896 | 909 |
897 | 910 |
898 extern const char * | 911 extern void |
899 message_filters_to_str(const lzma_filter *filters, bool all_known) | 912 message_filters_to_str(char buf[FILTERS_STR_SIZE], |
| 913 » » const lzma_filter *filters, bool all_known) |
900 { | 914 { |
901 static char buf[512]; | |
902 | |
903 char *pos = buf; | 915 char *pos = buf; |
904 » size_t left = sizeof(buf); | 916 » size_t left = FILTERS_STR_SIZE; |
905 | 917 |
906 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) { | 918 for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) { |
907 // Add the dashes for the filter option. A space is | 919 // Add the dashes for the filter option. A space is |
908 // needed after the first and later filters. | 920 // needed after the first and later filters. |
909 my_snprintf(&pos, &left, "%s", i == 0 ? "--" : " --"); | 921 my_snprintf(&pos, &left, "%s", i == 0 ? "--" : " --"); |
910 | 922 |
911 switch (filters[i].id) { | 923 switch (filters[i].id) { |
912 case LZMA_FILTER_LZMA1: | 924 case LZMA_FILTER_LZMA1: |
913 case LZMA_FILTER_LZMA2: { | 925 case LZMA_FILTER_LZMA2: { |
914 const lzma_options_lzma *opt = filters[i].options; | 926 const lzma_options_lzma *opt = filters[i].options; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 } | 1030 } |
1019 | 1031 |
1020 default: | 1032 default: |
1021 // This should be possible only if liblzma is | 1033 // This should be possible only if liblzma is |
1022 // newer than the xz tool. | 1034 // newer than the xz tool. |
1023 my_snprintf(&pos, &left, "UNKNOWN"); | 1035 my_snprintf(&pos, &left, "UNKNOWN"); |
1024 break; | 1036 break; |
1025 } | 1037 } |
1026 } | 1038 } |
1027 | 1039 |
1028 » return buf; | 1040 » return; |
1029 } | 1041 } |
1030 | 1042 |
1031 | 1043 |
1032 extern void | 1044 extern void |
1033 message_filters_show(enum message_verbosity v, const lzma_filter *filters) | 1045 message_filters_show(enum message_verbosity v, const lzma_filter *filters) |
1034 { | 1046 { |
1035 if (v > verbosity) | 1047 if (v > verbosity) |
1036 return; | 1048 return; |
1037 | 1049 |
1038 » fprintf(stderr, _("%s: Filter chain: %s\n"), progname, | 1050 » char buf[FILTERS_STR_SIZE]; |
1039 » » » message_filters_to_str(filters, true)); | 1051 » message_filters_to_str(buf, filters, true); |
| 1052 » fprintf(stderr, _("%s: Filter chain: %s\n"), progname, buf); |
1040 return; | 1053 return; |
1041 } | 1054 } |
1042 | 1055 |
1043 | 1056 |
1044 extern void | 1057 extern void |
1045 message_try_help(void) | 1058 message_try_help(void) |
1046 { | 1059 { |
1047 // Print this with V_WARNING instead of V_ERROR to prevent it from | 1060 // Print this with V_WARNING instead of V_ERROR to prevent it from |
1048 // showing up when --quiet has been specified. | 1061 // showing up when --quiet has been specified. |
1049 message(V_WARNING, _("Try `%s --help' for more information."), | 1062 message(V_WARNING, _("Try `%s --help' for more information."), |
1050 progname); | 1063 progname); |
1051 return; | 1064 return; |
1052 } | 1065 } |
1053 | 1066 |
1054 | 1067 |
1055 extern void | 1068 extern void |
1056 message_memlimit(void) | |
1057 { | |
1058 if (opt_robot) | |
1059 printf("%" PRIu64 "\n", hardware_memlimit_get()); | |
1060 else | |
1061 printf(_("%s MiB (%s bytes)\n"), | |
1062 uint64_to_str( | |
1063 round_up_to_mib(hardware_memlimit_get()), 0), | |
1064 uint64_to_str(hardware_memlimit_get(), 1)); | |
1065 | |
1066 tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT); | |
1067 } | |
1068 | |
1069 | |
1070 extern void | |
1071 message_version(void) | 1069 message_version(void) |
1072 { | 1070 { |
1073 // It is possible that liblzma version is different than the command | 1071 // It is possible that liblzma version is different than the command |
1074 // line tool version, so print both. | 1072 // line tool version, so print both. |
1075 if (opt_robot) { | 1073 if (opt_robot) { |
1076 » » printf("XZ_VERSION=%d\nLIBLZMA_VERSION=%d\n", | 1074 » » printf("XZ_VERSION=%" PRIu32 "\nLIBLZMA_VERSION=%" PRIu32 "\n", |
1077 LZMA_VERSION, lzma_version_number()); | 1075 LZMA_VERSION, lzma_version_number()); |
1078 } else { | 1076 } else { |
1079 printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n"); | 1077 printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n"); |
1080 printf("liblzma %s\n", lzma_version_string()); | 1078 printf("liblzma %s\n", lzma_version_string()); |
1081 } | 1079 } |
1082 | 1080 |
1083 tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT); | 1081 tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT); |
1084 } | 1082 } |
1085 | 1083 |
1086 | 1084 |
1087 extern void | 1085 extern void |
1088 message_help(bool long_help) | 1086 message_help(bool long_help) |
1089 { | 1087 { |
1090 printf(_("Usage: %s [OPTION]... [FILE]...\n" | 1088 printf(_("Usage: %s [OPTION]... [FILE]...\n" |
1091 "Compress or decompress FILEs in the .xz format.\n\n"), | 1089 "Compress or decompress FILEs in the .xz format.\n\n"), |
1092 progname); | 1090 progname); |
1093 | 1091 |
1094 » puts(_("Mandatory arguments to long options are mandatory for " | 1092 » // NOTE: The short help doesn't currently have options that |
1095 » » » "short options too.\n")); | 1093 » // take arguments. |
| 1094 » if (long_help) |
| 1095 » » puts(_("Mandatory arguments to long options are mandatory " |
| 1096 » » » » "for short options too.\n")); |
1096 | 1097 |
1097 if (long_help) | 1098 if (long_help) |
1098 puts(_(" Operation mode:\n")); | 1099 puts(_(" Operation mode:\n")); |
1099 | 1100 |
1100 puts(_( | 1101 puts(_( |
1101 " -z, --compress force compression\n" | 1102 " -z, --compress force compression\n" |
1102 " -d, --decompress force decompression\n" | 1103 " -d, --decompress force decompression\n" |
1103 " -t, --test test compressed file integrity\n" | 1104 " -t, --test test compressed file integrity\n" |
1104 " -l, --list list information about files")); | 1105 " -l, --list list information about .xz files")); |
1105 | 1106 |
1106 if (long_help) | 1107 if (long_help) |
1107 puts(_("\n Operation modifiers:\n")); | 1108 puts(_("\n Operation modifiers:\n")); |
1108 | 1109 |
1109 puts(_( | 1110 puts(_( |
1110 " -k, --keep keep (don't delete) input files\n" | 1111 " -k, --keep keep (don't delete) input files\n" |
1111 " -f, --force force overwrite of output file and (de)compress links\n" | 1112 " -f, --force force overwrite of output file and (de)compress links\n" |
1112 " -c, --stdout write to standard output and don't delete input files")); | 1113 " -c, --stdout write to standard output and don't delete input files")); |
1113 | 1114 |
1114 if (long_help) | 1115 if (long_help) |
1115 puts(_( | 1116 puts(_( |
1116 " --no-sparse do not create sparse files when decompressing\n" | 1117 " --no-sparse do not create sparse files when decompressing\n" |
1117 " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n" | 1118 " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n" |
1118 " --files=[FILE] read filenames to process from FILE; if FILE is\n" | 1119 " --files[=FILE] read filenames to process from FILE; if FILE is\n" |
1119 " omitted, filenames are read from the standard input;\n" | 1120 " omitted, filenames are read from the standard input;\n" |
1120 " filenames must be terminated with the newline character\n
" | 1121 " filenames must be terminated with the newline character\n
" |
1121 " --files0=[FILE] like --files but use the null character as terminator")); | 1122 " --files0[=FILE] like --files but use the null character as terminator")); |
1122 | 1123 |
1123 if (long_help) { | 1124 if (long_help) { |
1124 puts(_("\n Basic file format and compression options:\n")); | 1125 puts(_("\n Basic file format and compression options:\n")); |
1125 puts(_( | 1126 puts(_( |
1126 " -F, --format=FMT file format to encode or decode; possible values are\n" | 1127 " -F, --format=FMT file format to encode or decode; possible values are\n" |
1127 " `auto' (default), `xz', `lzma', and `raw'\n" | 1128 " `auto' (default), `xz', `lzma', and `raw'\n" |
1128 " -C, --check=CHECK integrity check type: `crc32', `crc64' (default),\n" | 1129 " -C, --check=CHECK integrity check type: `none' (use with caution),\n" |
1129 " `sha256', or `none' (use with caution)")); | 1130 " `crc32', `crc64' (default), or `sha256'")); |
1130 } | 1131 } |
1131 | 1132 |
1132 puts(_( | 1133 puts(_( |
1133 " -0 .. -9 compression preset; 0-2 fast compression, 3-5 good\n" | 1134 " -0 ... -9 compression preset; default is 6; take compressor *and*\n
" |
1134 " compression, 6-9 excellent compression; default is 6")); | 1135 " decompressor memory usage into account before using 7-9!"
)); |
1135 | 1136 |
1136 puts(_( | 1137 puts(_( |
1137 " -e, --extreme use more CPU time when encoding to increase compression\n
" | 1138 " -e, --extreme try to improve compression ratio by using more CPU time;\
n" |
1138 " ratio without increasing memory usage of the decoder")); | 1139 " does not affect decompressor memory requirements")); |
1139 | 1140 |
1140 if (long_help) { | 1141 if (long_help) { |
| 1142 puts(_( // xgettext:no-c-format |
| 1143 " --memlimit-compress=LIMIT\n" |
| 1144 " --memlimit-decompress=LIMIT\n" |
| 1145 " -M, --memlimit=LIMIT\n" |
| 1146 " set memory usage limit for compression, decompression,\n" |
| 1147 " or both; LIMIT is in bytes, % of RAM, or 0 for defaults")
); |
| 1148 |
1141 puts(_( | 1149 puts(_( |
1142 " --no-adjust if compression settings exceed the memory usage limit,\n" | 1150 " --no-adjust if compression settings exceed the memory usage limit,\n" |
1143 " give an error instead of adjusting the settings downwards
")); | 1151 " give an error instead of adjusting the settings downwards
")); |
1144 puts(_( // xgettext:no-c-format | |
1145 " -M, --memory=NUM use roughly NUM bytes of memory at maximum; 0 indicates\n
" | |
1146 " the default setting, which is 40 % of total RAM")); | |
1147 } | 1152 } |
1148 | 1153 |
1149 if (long_help) { | 1154 if (long_help) { |
1150 puts(_( | 1155 puts(_( |
1151 "\n Custom filter chain for compression (alternative for using presets):")); | 1156 "\n Custom filter chain for compression (alternative for using presets):")); |
1152 | 1157 |
1153 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) \ | 1158 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) \ |
1154 || defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2) | 1159 || defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2) |
| 1160 // TRANSLATORS: The word "literal" in "literal context bits" |
| 1161 // means how many "context bits" to use when encoding |
| 1162 // literals. A literal is a single 8-bit byte. It doesn't |
| 1163 // mean "literally" here. |
1155 puts(_( | 1164 puts(_( |
1156 "\n" | 1165 "\n" |
1157 " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or
\n" | 1166 " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or
\n" |
1158 " --lzma2[=OPTS] more of the following options (valid values; default):\n" | 1167 " --lzma2[=OPTS] more of the following options (valid values; default):\n" |
1159 " preset=NUM reset options to preset number NUM (0-9)\n" | 1168 " preset=PRE reset options to a preset (0-9[e])\n" |
1160 " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" | 1169 " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n" |
1161 " lc=NUM number of literal context bits (0-4; 3)\n" | 1170 " lc=NUM number of literal context bits (0-4; 3)\n" |
1162 " lp=NUM number of literal position bits (0-4; 0)\n" | 1171 " lp=NUM number of literal position bits (0-4; 0)\n" |
1163 " pb=NUM number of position bits (0-4; 2)\n" | 1172 " pb=NUM number of position bits (0-4; 2)\n" |
1164 " mode=MODE compression mode (fast, normal; normal)\n" | 1173 " mode=MODE compression mode (fast, normal; normal)\n" |
1165 " nice=NUM nice length of a match (2-273; 64)\n" | 1174 " nice=NUM nice length of a match (2-273; 64)\n" |
1166 " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\
n" | 1175 " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\
n" |
1167 " depth=NUM maximum search depth; 0=automatic (default)"
)); | 1176 " depth=NUM maximum search depth; 0=automatic (default)"
)); |
1168 #endif | 1177 #endif |
1169 | 1178 |
1170 puts(_( | 1179 puts(_( |
1171 "\n" | 1180 "\n" |
1172 " --x86[=OPTS] x86 BCJ filter\n" | 1181 " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n" |
1173 " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" | 1182 " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n" |
1174 " --ia64[=OPTS] IA64 (Itanium) BCJ filter\n" | 1183 " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n" |
1175 " --arm[=OPTS] ARM BCJ filter (little endian only)\n" | 1184 " --arm[=OPTS] ARM BCJ filter (little endian only)\n" |
1176 " --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n" | 1185 " --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n" |
1177 " --sparc[=OPTS] SPARC BCJ filter\n" | 1186 " --sparc[=OPTS] SPARC BCJ filter\n" |
1178 " Valid OPTS for all BCJ filters:\n" | 1187 " Valid OPTS for all BCJ filters:\n" |
1179 " start=NUM start offset for conversions (default=0)")); | 1188 " start=NUM start offset for conversions (default=0)")); |
1180 | 1189 |
1181 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA) | 1190 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA) |
1182 puts(_( | 1191 puts(_( |
1183 "\n" | 1192 "\n" |
1184 " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" | 1193 " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n" |
1185 " dist=NUM distance between bytes being subtracted\n" | 1194 " dist=NUM distance between bytes being subtracted\n" |
1186 " from each other (1-256; 1)")); | 1195 " from each other (1-256; 1)")); |
1187 #endif | 1196 #endif |
1188 } | 1197 } |
1189 | 1198 |
1190 if (long_help) | 1199 if (long_help) |
1191 puts(_("\n Other options:\n")); | 1200 puts(_("\n Other options:\n")); |
1192 | 1201 |
1193 puts(_( | 1202 puts(_( |
1194 " -q, --quiet suppress warnings; specify twice to suppress errors too\n
" | 1203 " -q, --quiet suppress warnings; specify twice to suppress errors too\n
" |
1195 " -v, --verbose be verbose; specify twice for even more verbose")); | 1204 " -v, --verbose be verbose; specify twice for even more verbose")); |
1196 | 1205 |
1197 if (long_help) { | 1206 if (long_help) { |
1198 puts(_( | 1207 puts(_( |
1199 " -Q, --no-warn make warnings not affect the exit status")); | 1208 " -Q, --no-warn make warnings not affect the exit status")); |
1200 puts(_( | 1209 puts(_( |
1201 " --robot use machine-parsable messages (useful for scripts)")); | 1210 " --robot use machine-parsable messages (useful for scripts)")); |
1202 puts(""); | 1211 puts(""); |
1203 puts(_( | 1212 puts(_( |
1204 " --info-memory display the memory usage limit and exit")); | 1213 " --info-memory display the total amount of RAM and the currently active\
n" |
| 1214 " memory usage limits, and exit")); |
1205 puts(_( | 1215 puts(_( |
1206 " -h, --help display the short help (lists only the basic options)\n" | 1216 " -h, --help display the short help (lists only the basic options)\n" |
1207 " -H, --long-help display this long help and exit")); | 1217 " -H, --long-help display this long help and exit")); |
1208 } else { | 1218 } else { |
1209 puts(_( | 1219 puts(_( |
1210 " -h, --help display this short help and exit\n" | 1220 " -h, --help display this short help and exit\n" |
1211 " -H, --long-help display the long help (lists also the advanced options)")
); | 1221 " -H, --long-help display the long help (lists also the advanced options)")
); |
1212 } | 1222 } |
1213 | 1223 |
1214 puts(_( | 1224 puts(_( |
1215 " -V, --version display the version number and exit")); | 1225 " -V, --version display the version number and exit")); |
1216 | 1226 |
1217 puts(_("\nWith no FILE, or when FILE is -, read standard input.\n")); | 1227 puts(_("\nWith no FILE, or when FILE is -, read standard input.\n")); |
1218 | 1228 |
1219 if (long_help) { | |
1220 printf(_( | |
1221 "On this system and configuration, this program will use a maximum of roughly\n" | |
1222 "%s MiB RAM and "), uint64_to_str(round_up_to_mib(hardware_memlimit_get()), 0)); | |
1223 printf(N_("one thread.\n\n", "%s threads.\n\n", | |
1224 hardware_threadlimit_get()), | |
1225 uint64_to_str(hardware_threadlimit_get(), 0)); | |
1226 } | |
1227 | |
1228 // TRANSLATORS: This message indicates the bug reporting address | 1229 // TRANSLATORS: This message indicates the bug reporting address |
1229 // for this package. Please add _another line_ saying | 1230 // for this package. Please add _another line_ saying |
1230 // "Report translation bugs to <...>\n" with the email or WWW | 1231 // "Report translation bugs to <...>\n" with the email or WWW |
1231 // address for translation bugs. Thanks. | 1232 // address for translation bugs. Thanks. |
1232 printf(_("Report bugs to <%s> (in English or Finnish).\n"), | 1233 printf(_("Report bugs to <%s> (in English or Finnish).\n"), |
1233 PACKAGE_BUGREPORT); | 1234 PACKAGE_BUGREPORT); |
1234 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); | 1235 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); |
1235 | 1236 |
1236 tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT); | 1237 tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT); |
1237 } | 1238 } |
OLD | NEW |