Rizin
unix-like reverse engineering framework and cli tools
message.c File Reference

Printing messages. More...

#include "private.h"
#include <stdarg.h>

Go to the source code of this file.

Functions

void message_init (void)
 Initializes the message functions. More...
 
void message_verbosity_increase (void)
 Increase verbosity level by one step unless it was at maximum. More...
 
void message_verbosity_decrease (void)
 Decrease verbosity level by one step unless it was at minimum. More...
 
enum message_verbosity message_verbosity_get (void)
 Get the current verbosity level. More...
 
void message_set_files (unsigned int files)
 Set the total number of files to be processed. More...
 
static void print_filename (void)
 
void message_filename (const char *src_name)
 Set the name of the current file and possibly print it too. More...
 
void message_progress_start (lzma_stream *strm, bool is_passthru, uint64_t in_size)
 Start progress info handling. More...
 
static const char * progress_percentage (uint64_t in_pos)
 Make the string indicating completion percentage. More...
 
static const char * progress_sizes (uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
 
static const char * progress_speed (uint64_t uncompressed_pos, uint64_t elapsed)
 Make the string containing the processing speed of uncompressed data. More...
 
static const char * progress_time (uint64_t mseconds)
 
static const char * progress_remaining (uint64_t in_pos, uint64_t elapsed)
 
static void progress_pos (uint64_t *in_pos, uint64_t *compressed_pos, uint64_t *uncompressed_pos)
 Get how much uncompressed and compressed data has been processed. More...
 
void message_progress_update (void)
 
static void progress_flush (bool finished)
 
void message_progress_end (bool success)
 Finishes the progress message if we were in verbose mode. More...
 
static void vmessage (enum message_verbosity v, const char *fmt, va_list ap)
 
void message (enum message_verbosity v, const char *fmt,...)
 
void message_warning (const char *fmt,...)
 
void message_error (const char *fmt,...)
 
void message_fatal (const char *fmt,...)
 
void message_bug (void)
 
void message_signal_handler (void)
 
const char * message_strm (lzma_ret code)
 Convert lzma_ret to a string. More...
 
void message_mem_needed (enum message_verbosity v, uint64_t memusage)
 Display how much memory was needed and how much the limit was. More...
 
static const char * uint32_to_optstr (uint32_t num)
 Convert uint32_t to a nice string for –lzma[12]=dict=SIZE. More...
 
void message_filters_to_str (char buf[FILTERS_STR_SIZE], const lzma_filter *filters, bool all_known)
 Get the filter chain as a string. More...
 
void message_filters_show (enum message_verbosity v, const lzma_filter *filters)
 Print the filter chain. More...
 
void message_try_help (void)
 Print a message that user should try –help. More...
 
void message_version (void)
 Prints the version number to stdout and exits with exit status SUCCESS. More...
 
void message_help (bool long_help)
 Print the help message. More...
 

Variables

static unsigned int files_pos = 0
 Number of the current file. More...
 
static unsigned int files_total
 Total number of input files; zero if unknown. More...
 
static enum message_verbosity verbosity = V_WARNING
 Verbosity level. More...
 
static const char * filename
 Filename which we will print with the verbose messages. More...
 
static bool first_filename_printed = false
 
static bool current_filename_printed = false
 
static bool progress_automatic
 
static bool progress_started = false
 
static bool progress_active = false
 
static lzma_streamprogress_strm
 Pointer to lzma_stream used to do the encoding or decoding. More...
 
static bool progress_is_from_passthru
 
static uint64_t expected_in_size
 
static bool progress_needs_updating = false
 
static uint64_t progress_next_update
 Elapsed time when the next progress message update should be done. More...
 

Detailed Description

Printing messages.

Definition in file message.c.

Function Documentation

◆ message()

void message ( enum message_verbosity  v,
const char *  fmt,
  ... 
)

Definition at line 740 of file message.c.

741 {
742  va_list ap;
743  va_start(ap, fmt);
744  vmessage(v, fmt, ap);
745  va_end(ap);
746  return;
747 }
const char * v
Definition: dsignal.c:12
static void vmessage(enum message_verbosity v, const char *fmt, va_list ap)
Definition: message.c:717

References v, and vmessage().

Referenced by message_mem_needed(), and message_try_help().

◆ message_bug()

void message_bug ( void  )

Print an error message that an internal error occurred and exit with EXIT_ERROR.

Definition at line 789 of file message.c.

790 {
791  message_fatal(_("Internal error (bug)"));
792 }
void message_fatal(const char *fmt,...)
Definition: message.c:777
#define _(String)
Definition: opintl.h:53

References _, and message_fatal().

Referenced by coder_init(), io_read(), options_lzma(), parse_block_header(), and parse_indexes().

◆ message_error()

void message_error ( const char *  fmt,
  ... 
)

Definition at line 764 of file message.c.

765 {
766  va_list ap;
767  va_start(ap, fmt);
768  vmessage(V_ERROR, fmt, ap);
769  va_end(ap);
770 
772  return;
773 }
@ V_ERROR
Only error messages.
Definition: message.h:16
void set_exit_status(enum exit_status_type new_status)
Definition: main.c:31
@ E_ERROR
Definition: transport.h:23

References E_ERROR, set_exit_status(), V_ERROR, and vmessage().

Referenced by coder_normal(), compressed_name(), io_close(), io_close_dest(), io_close_src(), io_open_dest_real(), io_open_src_real(), io_pread(), io_read(), io_unlink(), io_wait(), io_write(), io_write_buf(), is_empty_filename(), is_tty_stdin(), is_tty_stdout(), list_file(), main(), parse_block_header(), parse_indexes(), read_name(), and uncompressed_name().

◆ message_fatal()

void message_fatal ( const char *  fmt,
  ... 
)

Definition at line 777 of file message.c.

778 {
779  va_list ap;
780  va_start(ap, fmt);
781  vmessage(V_ERROR, fmt, ap);
782  va_end(ap);
783 
784  tuklib_exit(E_ERROR, E_ERROR, false);
785 }
#define tuklib_exit
Definition: tuklib_exit.h:20

References E_ERROR, tuklib_exit, V_ERROR, and vmessage().

Referenced by args_parse(), coder_add_filter(), coder_init(), io_init(), list_file(), lzma_attribute(), main(), message_bug(), message_signal_handler(), options_lzma(), parse_block_list(), parse_environment(), parse_options(), parse_real(), str_to_uint64(), suffix_set(), and xrealloc().

◆ message_filename()

void message_filename ( const char *  src_name)

Set the name of the current file and possibly print it too.

The name is printed immediately if –list was used or if –verbose was used and stderr is a terminal. Even when the filename isn't printed, it is stored so that it can be printed later if needed for progress messages.

Definition at line 232 of file message.c.

233 {
234  // Start numbering the files starting from one.
235  ++files_pos;
236  filename = src_name;
237 
238  if (verbosity >= V_VERBOSE
240  print_filename();
241  else
242  current_filename_printed = false;
243 
244  return;
245 }
enum operation_mode opt_mode
Definition: coder.c:24
@ MODE_LIST
Definition: coder.h:17
const char * filename
Definition: ioapi.h:137
static bool current_filename_printed
Definition: message.c:41
static bool progress_automatic
Definition: message.c:45
static enum message_verbosity verbosity
Verbosity level.
Definition: message.c:25
static unsigned int files_pos
Number of the current file.
Definition: message.c:19
static void print_filename(void)
Definition: message.c:200
@ V_VERBOSE
Errors, warnings, and verbose statistics.
Definition: message.h:18

References current_filename_printed, files_pos, MODE_LIST, opt_mode, print_filename(), progress_automatic, V_VERBOSE, and verbosity.

Referenced by coder_run(), and list_file().

◆ message_filters_show()

void message_filters_show ( enum message_verbosity  v,
const lzma_filter filters 
)

Print the filter chain.

Definition at line 1050 of file message.c.

1051 {
1052  if (v > verbosity)
1053  return;
1054 
1055  char buf[FILTERS_STR_SIZE];
1057  fprintf(stderr, _("%s: Filter chain: %s\n"), progname, buf);
1058  return;
1059 }
const lzma_filter * filters
Definition: container.h:315
voidpf void * buf
Definition: ioapi.h:138
void message_filters_to_str(char buf[FILTERS_STR_SIZE], const lzma_filter *filters, bool all_known)
Get the filter chain as a string.
Definition: message.c:917
#define FILTERS_STR_SIZE
Buffer size for message_filters_to_str()
Definition: message.h:94
#define progname

References _, filters, FILTERS_STR_SIZE, message_filters_to_str(), progname, v, and verbosity.

Referenced by coder_init().

◆ message_filters_to_str()

void message_filters_to_str ( char  buf[FILTERS_STR_SIZE],
const lzma_filter filters,
bool  all_known 
)

Get the filter chain as a string.

Parameters
bufPointer to caller allocated buffer to hold the filter chain string
filtersPointer to the filter chain
all_knownIf true, all filter options are printed. If false, only the options that get stored into .xz headers are printed.

Definition at line 917 of file message.c.

919 {
920  char *pos = buf;
921  size_t left = FILTERS_STR_SIZE;
922 
923  for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
924  // Add the dashes for the filter option. A space is
925  // needed after the first and later filters.
926  my_snprintf(&pos, &left, "%s", i == 0 ? "--" : " --");
927 
928  switch (filters[i].id) {
929  case LZMA_FILTER_LZMA1:
930  case LZMA_FILTER_LZMA2: {
931  const lzma_options_lzma *opt = filters[i].options;
932  const char *mode = NULL;
933  const char *mf = NULL;
934 
935  if (all_known) {
936  switch (opt->mode) {
937  case LZMA_MODE_FAST:
938  mode = "fast";
939  break;
940 
941  case LZMA_MODE_NORMAL:
942  mode = "normal";
943  break;
944 
945  default:
946  mode = "UNKNOWN";
947  break;
948  }
949 
950  switch (opt->mf) {
951  case LZMA_MF_HC3:
952  mf = "hc3";
953  break;
954 
955  case LZMA_MF_HC4:
956  mf = "hc4";
957  break;
958 
959  case LZMA_MF_BT2:
960  mf = "bt2";
961  break;
962 
963  case LZMA_MF_BT3:
964  mf = "bt3";
965  break;
966 
967  case LZMA_MF_BT4:
968  mf = "bt4";
969  break;
970 
971  default:
972  mf = "UNKNOWN";
973  break;
974  }
975  }
976 
977  // Add the filter name and dictionary size, which
978  // is always known.
979  my_snprintf(&pos, &left, "lzma%c=dict=%s",
981  ? '2' : '1',
983 
984  // With LZMA1 also lc/lp/pb are known when
985  // decompressing, but this function is never
986  // used to print information about .lzma headers.
988  || all_known);
989 
990  // Print the rest of the options, which are known
991  // only when compressing.
992  if (all_known)
993  my_snprintf(&pos, &left,
994  ",lc=%" PRIu32 ",lp=%" PRIu32
995  ",pb=%" PRIu32
996  ",mode=%s,nice=%" PRIu32 ",mf=%s"
997  ",depth=%" PRIu32,
998  opt->lc, opt->lp, opt->pb,
999  mode, opt->nice_len, mf, opt->depth);
1000  break;
1001  }
1002 
1003  case LZMA_FILTER_X86:
1004  case LZMA_FILTER_POWERPC:
1005  case LZMA_FILTER_IA64:
1006  case LZMA_FILTER_ARM:
1007  case LZMA_FILTER_ARMTHUMB:
1008  case LZMA_FILTER_SPARC: {
1009  static const char bcj_names[][9] = {
1010  "x86",
1011  "powerpc",
1012  "ia64",
1013  "arm",
1014  "armthumb",
1015  "sparc",
1016  };
1017 
1018  const lzma_options_bcj *opt = filters[i].options;
1019  my_snprintf(&pos, &left, "%s", bcj_names[filters[i].id
1020  - LZMA_FILTER_X86]);
1021 
1022  // Show the start offset only when really needed.
1023  if (opt != NULL && opt->start_offset != 0)
1024  my_snprintf(&pos, &left, "=start=%" PRIu32,
1025  opt->start_offset);
1026 
1027  break;
1028  }
1029 
1030  case LZMA_FILTER_DELTA: {
1031  const lzma_options_delta *opt = filters[i].options;
1032  my_snprintf(&pos, &left, "delta=dist=%" PRIu32,
1033  opt->dist);
1034  break;
1035  }
1036 
1037  default:
1038  // This should be possible only if liblzma is
1039  // newer than the xz tool.
1040  my_snprintf(&pos, &left, "UNKNOWN");
1041  break;
1042  }
1043  }
1044 
1045  return;
1046 }
lzma_index ** i
Definition: index.h:629
#define LZMA_FILTER_IA64
Definition: bcj.h:32
#define LZMA_FILTER_ARM
Definition: bcj.h:37
#define LZMA_FILTER_SPARC
Definition: bcj.h:47
#define LZMA_FILTER_ARMTHUMB
Definition: bcj.h:42
#define LZMA_FILTER_X86
Definition: bcj.h:22
#define LZMA_FILTER_POWERPC
Definition: bcj.h:27
#define NULL
Definition: cris-opc.c:27
#define LZMA_FILTER_DELTA
Filter ID.
Definition: delta.h:25
const char int mode
Definition: ioapi.h:137
#define PRIu32
Definition: macros.h:20
#define LZMA_FILTER_LZMA2
LZMA2 Filter ID.
Definition: lzma12.h:40
@ LZMA_MODE_FAST
Fast compression.
Definition: lzma12.h:139
@ LZMA_MODE_NORMAL
Normal compression.
Definition: lzma12.h:147
#define LZMA_FILTER_LZMA1
LZMA1 Filter ID.
Definition: lzma12.h:30
@ LZMA_MF_HC4
Hash Chain with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:70
@ LZMA_MF_BT4
Binary Tree with 2-, 3-, and 4-byte hashing.
Definition: lzma12.h:101
@ LZMA_MF_HC3
Hash Chain with 2- and 3-byte hashing.
Definition: lzma12.h:59
@ LZMA_MF_BT2
Binary Tree with 2-byte hashing.
Definition: lzma12.h:81
@ LZMA_MF_BT3
Binary Tree with 2- and 3-byte hashing.
Definition: lzma12.h:90
assert(limit<=UINT32_MAX/2)
static const char * uint32_to_optstr(uint32_t num)
Convert uint32_t to a nice string for –lzma[12]=dict=SIZE.
Definition: message.c:901
void * options
Pointer to filter-specific options structure.
Definition: filter.h:63
lzma_vli id
Filter ID.
Definition: filter.h:54
Options for BCJ filters.
Definition: bcj.h:73
uint32_t start_offset
Start offset for conversions.
Definition: bcj.h:88
Options for the Delta filter.
Definition: delta.h:45
uint32_t dist
Delta distance.
Definition: delta.h:59
Options specific to the LZMA1 and LZMA2 filters.
Definition: lzma12.h:185
uint32_t nice_len
Nice length of a match.
Definition: lzma12.h:342
uint32_t lp
Number of literal position bits.
Definition: lzma12.h:293
lzma_mode mode
Definition: lzma12.h:322
uint32_t depth
Maximum search depth in the match finder.
Definition: lzma12.h:375
uint32_t lc
Number of literal context bits.
Definition: lzma12.h:281
lzma_match_finder mf
Definition: lzma12.h:345
uint32_t pb
Number of position bits.
Definition: lzma12.h:316
uint32_t dict_size
Dictionary size in bytes.
Definition: lzma12.h:217
int pos
Definition: main.c:11
void my_snprintf(char **pos, size_t *left, const char *fmt,...)
Definition: util.c:239
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
Definition: vli.h:39

References assert(), lzma_options_lzma::depth, lzma_options_lzma::dict_size, lzma_options_delta::dist, filters, FILTERS_STR_SIZE, i, lzma_filter::id, lzma_options_lzma::lc, lzma_options_lzma::lp, LZMA_FILTER_ARM, LZMA_FILTER_ARMTHUMB, LZMA_FILTER_DELTA, LZMA_FILTER_IA64, LZMA_FILTER_LZMA1, LZMA_FILTER_LZMA2, LZMA_FILTER_POWERPC, LZMA_FILTER_SPARC, LZMA_FILTER_X86, LZMA_MF_BT2, LZMA_MF_BT3, LZMA_MF_BT4, LZMA_MF_HC3, LZMA_MF_HC4, LZMA_MODE_FAST, LZMA_MODE_NORMAL, LZMA_VLI_UNKNOWN, lzma_options_lzma::mf, lzma_options_lzma::mode, my_snprintf(), lzma_options_lzma::nice_len, NULL, lzma_filter::options, lzma_options_lzma::pb, pos, PRIu32, lzma_options_bcj::start_offset, and uint32_to_optstr().

Referenced by message_filters_show(), and parse_block_header().

◆ message_help()

void message_help ( bool  long_help)

Print the help message.

Definition at line 1091 of file message.c.

1092 {
1093  printf(_("Usage: %s [OPTION]... [FILE]...\n"
1094  "Compress or decompress FILEs in the .xz format.\n\n"),
1095  progname);
1096 
1097  // NOTE: The short help doesn't currently have options that
1098  // take arguments.
1099  if (long_help)
1100  puts(_("Mandatory arguments to long options are mandatory "
1101  "for short options too.\n"));
1102 
1103  if (long_help)
1104  puts(_(" Operation mode:\n"));
1105 
1106  puts(_(
1107 " -z, --compress force compression\n"
1108 " -d, --decompress force decompression\n"
1109 " -t, --test test compressed file integrity\n"
1110 " -l, --list list information about .xz files"));
1111 
1112  if (long_help)
1113  puts(_("\n Operation modifiers:\n"));
1114 
1115  puts(_(
1116 " -k, --keep keep (don't delete) input files\n"
1117 " -f, --force force overwrite of output file and (de)compress links\n"
1118 " -c, --stdout write to standard output and don't delete input files"));
1119 
1120  if (long_help) {
1121  puts(_(
1122 " --single-stream decompress only the first stream, and silently\n"
1123 " ignore possible remaining input data"));
1124  puts(_(
1125 " --no-sparse do not create sparse files when decompressing\n"
1126 " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
1127 " --files[=FILE] read filenames to process from FILE; if FILE is\n"
1128 " omitted, filenames are read from the standard input;\n"
1129 " filenames must be terminated with the newline character\n"
1130 " --files0[=FILE] like --files but use the null character as terminator"));
1131  }
1132 
1133  if (long_help) {
1134  puts(_("\n Basic file format and compression options:\n"));
1135  puts(_(
1136 " -F, --format=FMT file format to encode or decode; possible values are\n"
1137 " `auto' (default), `xz', `lzma', and `raw'\n"
1138 " -C, --check=CHECK integrity check type: `none' (use with caution),\n"
1139 " `crc32', `crc64' (default), or `sha256'"));
1140  puts(_(
1141 " --ignore-check don't verify the integrity check when decompressing"));
1142  }
1143 
1144  puts(_(
1145 " -0 ... -9 compression preset; default is 6; take compressor *and*\n"
1146 " decompressor memory usage into account before using 7-9!"));
1147 
1148  puts(_(
1149 " -e, --extreme try to improve compression ratio by using more CPU time;\n"
1150 " does not affect decompressor memory requirements"));
1151 
1152  puts(_(
1153 " -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
1154 " to use as many threads as there are processor cores"));
1155 
1156  if (long_help) {
1157  puts(_(
1158 " --block-size=SIZE\n"
1159 " start a new .xz block after every SIZE bytes of input;\n"
1160 " use this to set the block size for threaded compression"));
1161  puts(_(
1162 " --block-list=SIZES\n"
1163 " start a new .xz block after the given comma-separated\n"
1164 " intervals of uncompressed data"));
1165  puts(_(
1166 " --flush-timeout=TIMEOUT\n"
1167 " when compressing, if more than TIMEOUT milliseconds has\n"
1168 " passed since the previous flush and reading more input\n"
1169 " would block, all pending data is flushed out"
1170  ));
1171  puts(_( // xgettext:no-c-format
1172 " --memlimit-compress=LIMIT\n"
1173 " --memlimit-decompress=LIMIT\n"
1174 " -M, --memlimit=LIMIT\n"
1175 " set memory usage limit for compression, decompression,\n"
1176 " or both; LIMIT is in bytes, % of RAM, or 0 for defaults"));
1177 
1178  puts(_(
1179 " --no-adjust if compression settings exceed the memory usage limit,\n"
1180 " give an error instead of adjusting the settings downwards"));
1181  }
1182 
1183  if (long_help) {
1184  puts(_(
1185 "\n Custom filter chain for compression (alternative for using presets):"));
1186 
1187 #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) \
1188  || defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
1189  // TRANSLATORS: The word "literal" in "literal context bits"
1190  // means how many "context bits" to use when encoding
1191  // literals. A literal is a single 8-bit byte. It doesn't
1192  // mean "literally" here.
1193  puts(_(
1194 "\n"
1195 " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
1196 " --lzma2[=OPTS] more of the following options (valid values; default):\n"
1197 " preset=PRE reset options to a preset (0-9[e])\n"
1198 " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n"
1199 " lc=NUM number of literal context bits (0-4; 3)\n"
1200 " lp=NUM number of literal position bits (0-4; 0)\n"
1201 " pb=NUM number of position bits (0-4; 2)\n"
1202 " mode=MODE compression mode (fast, normal; normal)\n"
1203 " nice=NUM nice length of a match (2-273; 64)\n"
1204 " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
1205 " depth=NUM maximum search depth; 0=automatic (default)"));
1206 #endif
1207 
1208  puts(_(
1209 "\n"
1210 " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
1211 " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n"
1212 " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n"
1213 " --arm[=OPTS] ARM BCJ filter (little endian only)\n"
1214 " --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n"
1215 " --sparc[=OPTS] SPARC BCJ filter\n"
1216 " Valid OPTS for all BCJ filters:\n"
1217 " start=NUM start offset for conversions (default=0)"));
1218 
1219 #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
1220  puts(_(
1221 "\n"
1222 " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
1223 " dist=NUM distance between bytes being subtracted\n"
1224 " from each other (1-256; 1)"));
1225 #endif
1226  }
1227 
1228  if (long_help)
1229  puts(_("\n Other options:\n"));
1230 
1231  puts(_(
1232 " -q, --quiet suppress warnings; specify twice to suppress errors too\n"
1233 " -v, --verbose be verbose; specify twice for even more verbose"));
1234 
1235  if (long_help) {
1236  puts(_(
1237 " -Q, --no-warn make warnings not affect the exit status"));
1238  puts(_(
1239 " --robot use machine-parsable messages (useful for scripts)"));
1240  puts("");
1241  puts(_(
1242 " --info-memory display the total amount of RAM and the currently active\n"
1243 " memory usage limits, and exit"));
1244  puts(_(
1245 " -h, --help display the short help (lists only the basic options)\n"
1246 " -H, --long-help display this long help and exit"));
1247  } else {
1248  puts(_(
1249 " -h, --help display this short help and exit\n"
1250 " -H, --long-help display the long help (lists also the advanced options)"));
1251  }
1252 
1253  puts(_(
1254 " -V, --version display the version number and exit"));
1255 
1256  puts(_("\nWith no FILE, or when FILE is -, read standard input.\n"));
1257 
1258  // TRANSLATORS: This message indicates the bug reporting address
1259  // for this package. Please add _another line_ saying
1260  // "Report translation bugs to <...>\n" with the email or WWW
1261  // address for translation bugs. Thanks.
1262  printf(_("Report bugs to <%s> (in English or Finnish).\n"),
1264  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1265 
1266 #if LZMA_VERSION_STABILITY != LZMA_VERSION_STABILITY_STABLE
1267  puts(_(
1268 "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."));
1269 #endif
1270 
1272 }
#define PACKAGE_NAME
Definition: config.h:325
#define PACKAGE_BUGREPORT
Definition: config.h:322
#define PACKAGE_URL
Definition: config.h:334
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
@ E_SUCCESS
Definition: main.h:15
@ V_SILENT
No messages.
Definition: message.h:15

References _, E_ERROR, E_SUCCESS, PACKAGE_BUGREPORT, PACKAGE_NAME, PACKAGE_URL, printf(), progname, tuklib_exit, V_SILENT, and verbosity.

Referenced by parse_real().

◆ message_init()

void message_init ( void  )

Initializes the message functions.

If an error occurs, this function doesn't return.

Definition at line 114 of file message.c.

115 {
116  // If --verbose is used, we use a progress indicator if and only
117  // if stderr is a terminal. If stderr is not a terminal, we print
118  // verbose information only after finishing the file. As a special
119  // exception, even if --verbose was not used, user can send SIGALRM
120  // to make us print progress information once without automatic
121  // updating.
123 
124  // Commented out because COLUMNS is rarely exported to environment.
125  // Most users have at least 80 columns anyway, let's think something
126  // fancy here if enough people complain.
127 /*
128  if (progress_automatic) {
129  // stderr is a terminal. Check the COLUMNS environment
130  // variable to see if the terminal is wide enough. If COLUMNS
131  // doesn't exist or it has some unparsable value, we assume
132  // that the terminal is wide enough.
133  const char *columns_str = getenv("COLUMNS");
134  if (columns_str != NULL) {
135  char *endptr;
136  const long columns = strtol(columns_str, &endptr, 10);
137  if (*endptr != '\0' || columns < 80)
138  progress_automatic = false;
139  }
140  }
141 */
142 
143 #ifdef SIGALRM
144  // Establish the signal handlers which set a flag to tell us that
145  // progress info should be updated.
146  struct sigaction sa;
147  sigemptyset(&sa.sa_mask);
148  sa.sa_flags = 0;
149  sa.sa_handler = &progress_signal_handler;
150 
151  for (size_t i = 0; message_progress_sigs[i] != 0; ++i)
152  if (sigaction(message_progress_sigs[i], &sa, NULL))
154 #endif
155 
156  return;
157 }
void message_signal_handler(void)
Definition: message.c:796
const int message_progress_sigs[]
Signals used for progress message handling.
#define STDERR_FILENO
Definition: private.h:45

References i, message_progress_sigs, message_signal_handler(), NULL, progress_automatic, and STDERR_FILENO.

Referenced by main().

◆ message_mem_needed()

void message_mem_needed ( enum message_verbosity  v,
uint64_t  memusage 
)

Display how much memory was needed and how much the limit was.

Definition at line 846 of file message.c.

847 {
848  if (v > verbosity)
849  return;
850 
851  // Convert memusage to MiB, rounding up to the next full MiB.
852  // This way the user can always use the displayed usage as
853  // the new memory usage limit. (If we rounded to the nearest,
854  // the user might need to +1 MiB to get high enough limit.)
855  memusage = round_up_to_mib(memusage);
856 
858 
859  // Handle the case when there is no memory usage limit.
860  // This way we don't print a weird message with a huge number.
861  if (memlimit == UINT64_MAX) {
862  message(v, _("%s MiB of memory is required. "
863  "The limiter is disabled."),
864  uint64_to_str(memusage, 0));
865  return;
866  }
867 
868  // With US-ASCII:
869  // 2^64 with thousand separators + " MiB" suffix + '\0' = 26 + 4 + 1
870  // But there may be multibyte chars so reserve enough space.
871  char memlimitstr[128];
872 
873  // Show the memory usage limit as MiB unless it is less than 1 MiB.
874  // This way it's easy to notice errors where one has typed
875  // --memory=123 instead of --memory=123MiB.
876  if (memlimit < (UINT32_C(1) << 20)) {
877  snprintf(memlimitstr, sizeof(memlimitstr), "%s B",
878  uint64_to_str(memlimit, 1));
879  } else {
880  // Round up just like with memusage. If this function is
881  // called for informational purposes (to just show the
882  // current usage and limit), we should never show that
883  // the usage is higher than the limit, which would give
884  // a false impression that the memory usage limit isn't
885  // properly enforced.
886  snprintf(memlimitstr, sizeof(memlimitstr), "%s MiB",
888  }
889 
890  message(v, _("%s MiB of memory is required. The limit is %s."),
891  uint64_to_str(memusage, 0), memlimitstr);
892 
893  return;
894 }
uint64_t memlimit
Definition: container.h:537
uint64_t hardware_memlimit_get(enum operation_mode mode)
Get the current memory usage limit for compression or decompression.
Definition: hardware.c:112
snprintf
Definition: kernel.h:364
void message(enum message_verbosity v, const char *fmt,...)
Definition: message.c:740
unsigned long uint64_t
Definition: sftypes.h:28
#define UINT32_C(val)
#define UINT64_MAX
const char * uint64_to_str(uint64_t value, uint32_t slot)
Convert uint64_t to a string.
Definition: util.c:171
uint64_t round_up_to_mib(uint64_t n)
Round an integer up to the next full MiB and convert to MiB.
Definition: util.c:139

References _, hardware_memlimit_get(), memlimit, message(), opt_mode, round_up_to_mib(), snprintf, UINT32_C, UINT64_MAX, uint64_to_str(), v, and verbosity.

Referenced by coder_init(), coder_normal(), lzma_attribute(), and parse_indexes().

◆ message_progress_end()

void message_progress_end ( bool  finished)

Finishes the progress message if we were in verbose mode.

Parameters
finishedTrue if the whole stream was successfully coded and output written to the output stream.

Definition at line 707 of file message.c.

708 {
710  progress_flush(success);
711  progress_started = false;
712  return;
713 }
static bool progress_started
Definition: message.c:49
static void progress_flush(bool finished)
Definition: message.c:629

References assert(), progress_flush(), and progress_started.

Referenced by coder_run().

◆ message_progress_start()

void message_progress_start ( lzma_stream strm,
bool  is_passthru,
uint64_t  in_size 
)

Start progress info handling.

message_filename() must be called before this function to set the filename.

This must be paired with a call to message_progress_end() before the given *strm becomes invalid.

Parameters
strmPointer to lzma_stream used for the coding.
in_sizeSize of the input file, or zero if unknown.

Definition at line 249 of file message.c.

250 {
251  // Store the pointer to the lzma_stream used to do the coding.
252  // It is needed to find out the position in the stream.
254  progress_is_from_passthru = is_passthru;
255 
256  // Store the expected size of the file. If we aren't printing any
257  // statistics, then is will be unused. But since it is possible
258  // that the user sends us a signal to show statistics, we need
259  // to have it available anyway.
261 
262  // Indicate that progress info may need to be printed before
263  // printing error messages.
264  progress_started = true;
265 
266  // If progress indicator is wanted, print the filename and possibly
267  // the file count now.
269  // Start the timer to display the first progress message
270  // after one second. An alternative would be to show the
271  // first message almost immediately, but delaying by one
272  // second looks better to me, since extremely early
273  // progress info is pretty much useless.
274 #ifdef SIGALRM
275  // First disable a possibly existing alarm.
276  alarm(0);
277  progress_needs_updating = false;
278  alarm(1);
279 #else
281  progress_next_update = 1000;
282 #endif
283  }
284 
285  return;
286 }
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
static lzma_stream strm
Definition: full_flush.c:20
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t alarm
Definition: sflib.h:55
static uint64_t progress_next_update
Elapsed time when the next progress message update should be done.
Definition: message.c:108
static bool progress_is_from_passthru
Definition: message.c:62
static bool progress_needs_updating
Definition: message.c:105
static lzma_stream * progress_strm
Pointer to lzma_stream used to do the encoding or decoding.
Definition: message.c:57
static uint64_t expected_in_size
Definition: message.c:66

References alarm, expected_in_size, in_size, progress_automatic, progress_is_from_passthru, progress_needs_updating, progress_next_update, progress_started, progress_strm, strm, V_VERBOSE, and verbosity.

Referenced by coder_run().

◆ message_progress_update()

void message_progress_update ( void  )

Update the progress info if in verbose mode and enough time has passed since the previous update. This can be called only when message_progress_start() has already been used.

Definition at line 545 of file message.c.

546 {
548  return;
549 
550  // Calculate how long we have been processing this file.
551  const uint64_t elapsed = mytime_get_elapsed();
552 
553 #ifndef SIGALRM
554  if (progress_next_update > elapsed)
555  return;
556 
557  progress_next_update = elapsed + 1000;
558 #endif
559 
560  // Get our current position in the stream.
562  uint64_t compressed_pos;
563  uint64_t uncompressed_pos;
564  progress_pos(&in_pos, &compressed_pos, &uncompressed_pos);
565 
566  // Block signals so that fprintf() doesn't get interrupted.
567  signals_block();
568 
569  // Print the filename if it hasn't been printed yet.
571  print_filename();
572 
573  // Print the actual progress message. The idea is that there is at
574  // least three spaces between the fields in typical situations, but
575  // even in rare situations there is at least one space.
576  const char *cols[5] = {
578  progress_sizes(compressed_pos, uncompressed_pos, false),
579  progress_speed(uncompressed_pos, elapsed),
580  progress_time(elapsed),
581  progress_remaining(in_pos, elapsed),
582  };
583  fprintf(stderr, "\r %*s %*s %*s %10s %10s\r",
584  tuklib_mbstr_fw(cols[0], 6), cols[0],
585  tuklib_mbstr_fw(cols[1], 35), cols[1],
586  tuklib_mbstr_fw(cols[2], 9), cols[2],
587  cols[3],
588  cols[4]);
589 
590 #ifdef SIGALRM
591  // Updating the progress info was finished. Reset
592  // progress_needs_updating to wait for the next SIGALRM.
593  //
594  // NOTE: This has to be done before alarm(1) or with (very) bad
595  // luck we could be setting this to false after the alarm has already
596  // been triggered.
597  progress_needs_updating = false;
598 
600  // Mark that the progress indicator is active, so if an error
601  // occurs, the error message gets printed cleanly.
602  progress_active = true;
603 
604  // Restart the timer so that progress_needs_updating gets
605  // set to true after about one second.
606  alarm(1);
607  } else {
608  // The progress message was printed because user had sent us
609  // SIGALRM. In this case, each progress message is printed
610  // on its own line.
611  fputc('\n', stderr);
612  }
613 #else
614  // When SIGALRM isn't supported and we get here, it's always due to
615  // automatic progress update. We set progress_active here too like
616  // described above.
619  progress_active = true;
620 #endif
621 
622  signals_unblock();
623 
624  return;
625 }
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579
static const char * progress_percentage(uint64_t in_pos)
Make the string indicating completion percentage.
Definition: message.c:291
static void progress_pos(uint64_t *in_pos, uint64_t *compressed_pos, uint64_t *uncompressed_pos)
Get how much uncompressed and compressed data has been processed.
Definition: message.c:512
static const char * progress_speed(uint64_t uncompressed_pos, uint64_t elapsed)
Make the string containing the processing speed of uncompressed data.
Definition: message.c:351
static bool progress_active
Definition: message.c:54
static const char * progress_time(uint64_t mseconds)
Definition: message.c:393
static const char * progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
Definition: message.c:315
static const char * progress_remaining(uint64_t in_pos, uint64_t elapsed)
Definition: message.c:426
uint64_t mytime_get_elapsed(void)
Get the number of milliseconds since the operation started.
Definition: mytime.c:59
void signals_unblock(void)
Unblock the signals blocked by signals_block().
Definition: signals.c:135
void signals_block(void)
Definition: signals.c:120
#define tuklib_mbstr_fw
Definition: tuklib_mbstr.h:45

References alarm, assert(), current_filename_printed, in_pos, mytime_get_elapsed(), print_filename(), progress_active, progress_automatic, progress_needs_updating, progress_next_update, progress_percentage(), progress_pos(), progress_remaining(), progress_sizes(), progress_speed(), progress_time(), signals_block(), signals_unblock(), tuklib_mbstr_fw, V_VERBOSE, and verbosity.

Referenced by coder_normal(), and coder_passthru().

◆ message_set_files()

void message_set_files ( unsigned int  files)

Set the total number of files to be processed.

Standard input is counted as a file here. This is used when printing the filename via message_filename().

Definition at line 188 of file message.c.

189 {
190  files_total = files;
191  return;
192 }
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type special files
Definition: file_opts.h:46
static unsigned int files_total
Total number of input files; zero if unknown.
Definition: message.c:22

References files, and files_total.

Referenced by main().

◆ message_signal_handler()

void message_signal_handler ( void  )

Print a message that establishing signal handlers failed, and exit with exit status ERROR.

Definition at line 796 of file message.c.

797 {
798  message_fatal(_("Cannot establish signal handlers"));
799 }

References _, and message_fatal().

Referenced by message_init(), and signals_init().

◆ message_strm()

const char* message_strm ( lzma_ret  code)

Convert lzma_ret to a string.

Definition at line 803 of file message.c.

804 {
805  switch (code) {
806  case LZMA_NO_CHECK:
807  return _("No integrity check; not verifying file integrity");
808 
810  return _("Unsupported type of integrity check; "
811  "not verifying file integrity");
812 
813  case LZMA_MEM_ERROR:
814  return strerror(ENOMEM);
815 
816  case LZMA_MEMLIMIT_ERROR:
817  return _("Memory usage limit reached");
818 
819  case LZMA_FORMAT_ERROR:
820  return _("File format not recognized");
821 
822  case LZMA_OPTIONS_ERROR:
823  return _("Unsupported options");
824 
825  case LZMA_DATA_ERROR:
826  return _("Compressed data is corrupt");
827 
828  case LZMA_BUF_ERROR:
829  return _("Unexpected end of input");
830 
831  case LZMA_OK:
832  case LZMA_STREAM_END:
833  case LZMA_GET_CHECK:
834  case LZMA_PROG_ERROR:
835  // Without "default", compiler will warn if new constants
836  // are added to lzma_ret, it is not too easy to forget to
837  // add the new constants to this function.
838  break;
839  }
840 
841  return _("Internal error (bug)");
842 }
#define ENOMEM
Definition: sftypes.h:122
Definition: inftree9.h:24
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_DATA_ERROR
Data is corrupt.
Definition: base.h:172
@ LZMA_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128
@ LZMA_FORMAT_ERROR
Memory usage limit was reached.
Definition: base.h:150
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_UNSUPPORTED_CHECK
Cannot calculate the integrity check.
Definition: base.h:90
@ LZMA_BUF_ERROR
No progress is possible.
Definition: base.h:191
@ LZMA_MEMLIMIT_ERROR
Definition: base.h:140
@ LZMA_GET_CHECK
Integrity check type is now available.
Definition: base.h:115
@ LZMA_NO_CHECK
Input stream has no integrity check.
Definition: base.h:75
@ LZMA_OPTIONS_ERROR
Invalid or unsupported options.
Definition: base.h:160
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58

References _, ENOMEM, LZMA_BUF_ERROR, LZMA_DATA_ERROR, LZMA_FORMAT_ERROR, LZMA_GET_CHECK, LZMA_MEM_ERROR, LZMA_MEMLIMIT_ERROR, LZMA_NO_CHECK, LZMA_OK, LZMA_OPTIONS_ERROR, LZMA_PROG_ERROR, LZMA_STREAM_END, and LZMA_UNSUPPORTED_CHECK.

Referenced by coder_normal(), parse_block_header(), and parse_indexes().

◆ message_try_help()

void message_try_help ( void  )

Print a message that user should try –help.

Definition at line 1063 of file message.c.

1064 {
1065  // Print this with V_WARNING instead of V_ERROR to prevent it from
1066  // showing up when --quiet has been specified.
1067  message(V_WARNING, _("Try `%s --help' for more information."),
1068  progname);
1069  return;
1070 }
@ V_WARNING
Errors and warnings.
Definition: message.h:17

References _, message(), progname, and V_WARNING.

Referenced by main(), and parse_real().

◆ message_verbosity_decrease()

void message_verbosity_decrease ( void  )

Decrease verbosity level by one step unless it was at minimum.

Definition at line 171 of file message.c.

172 {
173  if (verbosity > V_SILENT)
174  --verbosity;
175 
176  return;
177 }

References V_SILENT, and verbosity.

Referenced by parse_real().

◆ message_verbosity_get()

enum message_verbosity message_verbosity_get ( void  )

Get the current verbosity level.

Definition at line 171 of file message.c.

182 {
183  return verbosity;
184 }

Referenced by hardware_memlimit_show(), list_file(), list_totals(), main(), print_info_adv(), print_info_robot(), print_totals_adv(), and print_totals_robot().

◆ message_verbosity_increase()

void message_verbosity_increase ( void  )

Increase verbosity level by one step unless it was at maximum.

Definition at line 161 of file message.c.

162 {
163  if (verbosity < V_DEBUG)
164  ++verbosity;
165 
166  return;
167 }
@ V_DEBUG
Very verbose.
Definition: message.h:19

References V_DEBUG, and verbosity.

Referenced by parse_real().

◆ message_version()

void message_version ( void  )

Prints the version number to stdout and exits with exit status SUCCESS.

Definition at line 1074 of file message.c.

1075 {
1076  // It is possible that liblzma version is different than the command
1077  // line tool version, so print both.
1078  if (opt_robot) {
1079  printf("XZ_VERSION=%" PRIu32 "\nLIBLZMA_VERSION=%" PRIu32 "\n",
1080  LZMA_VERSION, lzma_version_number());
1081  } else {
1082  printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
1083  printf("liblzma %s\n", lzma_version_string());
1084  }
1085 
1087 }
bool opt_robot
Definition: args.c:24
#define LZMA_VERSION
Compile-time version number.
Definition: version.h:57
#define LZMA_VERSION_STRING
Compile-time version as a string.
Definition: version.h:92

References E_ERROR, E_SUCCESS, LZMA_VERSION, LZMA_VERSION_STRING, opt_robot, PACKAGE_NAME, printf(), PRIu32, tuklib_exit, V_SILENT, and verbosity.

Referenced by parse_real().

◆ message_warning()

void message_warning ( const char *  fmt,
  ... 
)

Definition at line 751 of file message.c.

752 {
753  va_list ap;
754  va_start(ap, fmt);
755  vmessage(V_WARNING, fmt, ap);
756  va_end(ap);
757 
759  return;
760 }
@ E_WARNING
Definition: main.h:17

References E_WARNING, set_exit_status(), V_WARNING, and vmessage().

Referenced by coder_normal(), io_copy_attrs(), io_open_src_real(), msg_suffix(), and uncompressed_name().

◆ print_filename()

static void print_filename ( void  )
static

Prints the name of the current file if it hasn't been printed already, except if we are processing exactly one stream from stdin to stdout. I think it looks nicer to not print "(stdin)" when –verbose is used in a pipe and no other files are processed.

Definition at line 200 of file message.c.

201 {
202  if (!opt_robot && (files_total != 1 || filename != stdin_filename)) {
203  signals_block();
204 
205  FILE *file = opt_mode == MODE_LIST ? stdout : stderr;
206 
207  // If a file was already processed, put an empty line
208  // before the next filename to improve readability.
210  fputc('\n', file);
211 
212  first_filename_printed = true;
214 
215  // If we don't know how many files there will be due
216  // to usage of --files or --files0.
217  if (files_total == 0)
218  fprintf(file, "%s (%u)\n", filename,
219  files_pos);
220  else
221  fprintf(file, "%s (%u/%u)\n", filename,
223 
224  signals_unblock();
225  }
226 
227  return;
228 }
const char stdin_filename[]
Definition: args.c:29
static bool first_filename_printed
Definition: message.c:35
string FILE
Definition: benchmark.py:21
Definition: gzappend.c:170

References current_filename_printed, benchmark::FILE, files_pos, files_total, first_filename_printed, MODE_LIST, opt_mode, opt_robot, signals_block(), signals_unblock(), and stdin_filename.

Referenced by message_filename(), and message_progress_update().

◆ progress_flush()

static void progress_flush ( bool  finished)
static

Definition at line 629 of file message.c.

630 {
632  return;
633 
635  uint64_t compressed_pos;
636  uint64_t uncompressed_pos;
637  progress_pos(&in_pos, &compressed_pos, &uncompressed_pos);
638 
639  // Avoid printing intermediate progress info if some error occurs
640  // in the beginning of the stream. (If something goes wrong later in
641  // the stream, it is sometimes useful to tell the user where the
642  // error approximately occurred, especially if the error occurs
643  // after a time-consuming operation.)
644  if (!finished && !progress_active
645  && (compressed_pos == 0 || uncompressed_pos == 0))
646  return;
647 
648  progress_active = false;
649 
650  const uint64_t elapsed = mytime_get_elapsed();
651 
652  signals_block();
653 
654  // When using the auto-updating progress indicator, the final
655  // statistics are printed in the same format as the progress
656  // indicator itself.
657  if (progress_automatic) {
658  const char *cols[5] = {
659  finished ? "100 %" : progress_percentage(in_pos),
660  progress_sizes(compressed_pos, uncompressed_pos, true),
661  progress_speed(uncompressed_pos, elapsed),
662  progress_time(elapsed),
663  finished ? "" : progress_remaining(in_pos, elapsed),
664  };
665  fprintf(stderr, "\r %*s %*s %*s %10s %10s\n",
666  tuklib_mbstr_fw(cols[0], 6), cols[0],
667  tuklib_mbstr_fw(cols[1], 35), cols[1],
668  tuklib_mbstr_fw(cols[2], 9), cols[2],
669  cols[3],
670  cols[4]);
671  } else {
672  // The filename is always printed.
673  fprintf(stderr, "%s: ", filename);
674 
675  // Percentage is printed only if we didn't finish yet.
676  if (!finished) {
677  // Don't print the percentage when it isn't known
678  // (starts with a dash).
679  const char *percentage = progress_percentage(in_pos);
680  if (percentage[0] != '-')
681  fprintf(stderr, "%s, ", percentage);
682  }
683 
684  // Size information is always printed.
685  fprintf(stderr, "%s", progress_sizes(
686  compressed_pos, uncompressed_pos, true));
687 
688  // The speed and elapsed time aren't always shown.
689  const char *speed = progress_speed(uncompressed_pos, elapsed);
690  if (speed[0] != '\0')
691  fprintf(stderr, ", %s", speed);
692 
693  const char *elapsed_str = progress_time(elapsed);
694  if (elapsed_str[0] != '\0')
695  fprintf(stderr, ", %s", elapsed_str);
696 
697  fputc('\n', stderr);
698  }
699 
700  signals_unblock();
701 
702  return;
703 }
double percentage
Definition: main.c:10

References in_pos, mytime_get_elapsed(), percentage, progress_active, progress_automatic, progress_percentage(), progress_pos(), progress_remaining(), progress_sizes(), progress_speed(), progress_started, progress_time(), signals_block(), signals_unblock(), tuklib_mbstr_fw, V_VERBOSE, and verbosity.

Referenced by message_progress_end(), and vmessage().

◆ progress_percentage()

static const char* progress_percentage ( uint64_t  in_pos)
static

Make the string indicating completion percentage.

Definition at line 291 of file message.c.

292 {
293  // If the size of the input file is unknown or the size told us is
294  // clearly wrong since we have processed more data than the alleged
295  // size of the file, show a static string indicating that we have
296  // no idea of the completion percentage.
298  return "--- %";
299 
300  // Never show 100.0 % before we actually are finished.
301  double percentage = (double)(in_pos) / (double)(expected_in_size)
302  * 99.9;
303 
304  // Use big enough buffer to hold e.g. a multibyte decimal point.
305  static char buf[16];
306  snprintf(buf, sizeof(buf), "%.1f %%", percentage);
307 
308  return buf;
309 }

References expected_in_size, in_pos, percentage, and snprintf.

Referenced by message_progress_update(), and progress_flush().

◆ progress_pos()

static void progress_pos ( uint64_t in_pos,
uint64_t compressed_pos,
uint64_t uncompressed_pos 
)
static

Get how much uncompressed and compressed data has been processed.

Definition at line 512 of file message.c.

514 {
517  // In passthru mode the progress info is in total_in/out but
518  // the *progress_strm itself isn't initialized and thus we
519  // cannot use lzma_get_progress().
522  } else {
523  lzma_get_progress(progress_strm, in_pos, &out_pos);
524  }
525 
526  // It cannot have processed more input than it has been given.
527  assert(*in_pos <= progress_strm->total_in);
528 
529  // It cannot have produced more output than it claims to have ready.
531 
532  if (opt_mode == MODE_COMPRESS) {
533  *compressed_pos = out_pos;
534  *uncompressed_pos = *in_pos;
535  } else {
536  *compressed_pos = *in_pos;
537  *uncompressed_pos = out_pos;
538  }
539 
540  return;
541 }
const lzma_allocator const uint8_t size_t uint8_t size_t * out_pos
Definition: block.h:528
@ MODE_COMPRESS
Definition: coder.h:14
uint64_t total_in
Definition: base.h:488
uint64_t total_out
Definition: base.h:492

References assert(), in_pos, MODE_COMPRESS, opt_mode, out_pos, progress_is_from_passthru, progress_strm, lzma_stream::total_in, and lzma_stream::total_out.

Referenced by message_progress_update(), and progress_flush().

◆ progress_remaining()

static const char* progress_remaining ( uint64_t  in_pos,
uint64_t  elapsed 
)
static

Return a string containing estimated remaining time when reasonably possible.

Definition at line 426 of file message.c.

427 {
428  // Don't show the estimated remaining time when it wouldn't
429  // make sense:
430  // - Input size is unknown.
431  // - Input has grown bigger since we started (de)compressing.
432  // - We haven't processed much data yet, so estimate would be
433  // too inaccurate.
434  // - Only a few seconds has passed since we started (de)compressing,
435  // so estimate would be too inaccurate.
437  || in_pos < (UINT64_C(1) << 19) || elapsed < 8000)
438  return "";
439 
440  // Calculate the estimate. Don't give an estimate of zero seconds,
441  // since it is possible that all the input has been already passed
442  // to the library, but there is still quite a bit of output pending.
443  uint32_t remaining = (uint32_t)((double)(expected_in_size - in_pos)
444  * ((double)(elapsed) / 1000.0) / (double)(in_pos));
445  if (remaining < 1)
446  remaining = 1;
447 
448  static char buf[sizeof("9 h 55 min")];
449 
450  // Select appropriate precision for the estimated remaining time.
451  if (remaining <= 10) {
452  // A maximum of 10 seconds remaining.
453  // Show the number of seconds as is.
454  snprintf(buf, sizeof(buf), "%" PRIu32 " s", remaining);
455 
456  } else if (remaining <= 50) {
457  // A maximum of 50 seconds remaining.
458  // Round up to the next multiple of five seconds.
459  remaining = (remaining + 4) / 5 * 5;
460  snprintf(buf, sizeof(buf), "%" PRIu32 " s", remaining);
461 
462  } else if (remaining <= 590) {
463  // A maximum of 9 minutes and 50 seconds remaining.
464  // Round up to the next multiple of ten seconds.
465  remaining = (remaining + 9) / 10 * 10;
466  snprintf(buf, sizeof(buf), "%" PRIu32 " min %" PRIu32 " s",
467  remaining / 60, remaining % 60);
468 
469  } else if (remaining <= 59 * 60) {
470  // A maximum of 59 minutes remaining.
471  // Round up to the next multiple of a minute.
472  remaining = (remaining + 59) / 60;
473  snprintf(buf, sizeof(buf), "%" PRIu32 " min", remaining);
474 
475  } else if (remaining <= 9 * 3600 + 50 * 60) {
476  // A maximum of 9 hours and 50 minutes left.
477  // Round up to the next multiple of ten minutes.
478  remaining = (remaining + 599) / 600 * 10;
479  snprintf(buf, sizeof(buf), "%" PRIu32 " h %" PRIu32 " min",
480  remaining / 60, remaining % 60);
481 
482  } else if (remaining <= 23 * 3600) {
483  // A maximum of 23 hours remaining.
484  // Round up to the next multiple of an hour.
485  remaining = (remaining + 3599) / 3600;
486  snprintf(buf, sizeof(buf), "%" PRIu32 " h", remaining);
487 
488  } else if (remaining <= 9 * 24 * 3600 + 23 * 3600) {
489  // A maximum of 9 days and 23 hours remaining.
490  // Round up to the next multiple of an hour.
491  remaining = (remaining + 3599) / 3600;
492  snprintf(buf, sizeof(buf), "%" PRIu32 " d %" PRIu32 " h",
493  remaining / 24, remaining % 24);
494 
495  } else if (remaining <= 999 * 24 * 3600) {
496  // A maximum of 999 days remaining. ;-)
497  // Round up to the next multiple of a day.
498  remaining = (remaining + 24 * 3600 - 1) / (24 * 3600);
499  snprintf(buf, sizeof(buf), "%" PRIu32 " d", remaining);
500 
501  } else {
502  // The estimated remaining time is too big. Don't show it.
503  return "";
504  }
505 
506  return buf;
507 }
unsigned int uint32_t
Definition: sftypes.h:29
#define UINT64_C(val)

References expected_in_size, in_pos, PRIu32, snprintf, and UINT64_C.

Referenced by message_progress_update(), and progress_flush().

◆ progress_sizes()

static const char* progress_sizes ( uint64_t  compressed_pos,
uint64_t  uncompressed_pos,
bool  final 
)
static

Make the string containing the amount of input processed, amount of output produced, and the compression ratio.

Definition at line 315 of file message.c.

316 {
317  // Use big enough buffer to hold e.g. a multibyte thousand separators.
318  static char buf[128];
319  char *pos = buf;
320  size_t left = sizeof(buf);
321 
322  // Print the sizes. If this the final message, use more reasonable
323  // units than MiB if the file was small.
324  const enum nicestr_unit unit_min = final ? NICESTR_B : NICESTR_MIB;
325  my_snprintf(&pos, &left, "%s / %s",
326  uint64_to_nicestr(compressed_pos,
327  unit_min, NICESTR_TIB, false, 0),
328  uint64_to_nicestr(uncompressed_pos,
329  unit_min, NICESTR_TIB, false, 1));
330 
331  // Avoid division by zero. If we cannot calculate the ratio, set
332  // it to some nice number greater than 10.0 so that it gets caught
333  // in the next if-clause.
334  const double ratio = uncompressed_pos > 0
335  ? (double)(compressed_pos) / (double)(uncompressed_pos)
336  : 16.0;
337 
338  // If the ratio is very bad, just indicate that it is greater than
339  // 9.999. This way the length of the ratio field stays fixed.
340  if (ratio > 9.999)
341  snprintf(pos, left, " > %.3f", 9.999);
342  else
343  snprintf(pos, left, " = %.3f", ratio);
344 
345  return buf;
346 }
const char * uint64_to_nicestr(uint64_t value, enum nicestr_unit unit_min, enum nicestr_unit unit_max, bool always_also_bytes, uint32_t slot)
Convert uint64_t to a nice human readable string.
Definition: util.c:187
nicestr_unit
Definition: util.h:64
@ NICESTR_MIB
Definition: util.h:67
@ NICESTR_B
Definition: util.h:65
@ NICESTR_TIB
Definition: util.h:69

References my_snprintf(), NICESTR_B, NICESTR_MIB, NICESTR_TIB, pos, snprintf, and uint64_to_nicestr().

Referenced by message_progress_update(), and progress_flush().

◆ progress_speed()

static const char* progress_speed ( uint64_t  uncompressed_pos,
uint64_t  elapsed 
)
static

Make the string containing the processing speed of uncompressed data.

Definition at line 351 of file message.c.

352 {
353  // Don't print the speed immediately, since the early values look
354  // somewhat random.
355  if (elapsed < 3000)
356  return "";
357 
358  static const char unit[][8] = {
359  "KiB/s",
360  "MiB/s",
361  "GiB/s",
362  };
363 
364  size_t unit_index = 0;
365 
366  // Calculate the speed as KiB/s.
367  double speed = (double)(uncompressed_pos)
368  / ((double)(elapsed) * (1024.0 / 1000.0));
369 
370  // Adjust the unit of the speed if needed.
371  while (speed > 999.0) {
372  speed /= 1024.0;
373  if (++unit_index == ARRAY_SIZE(unit))
374  return ""; // Way too fast ;-)
375  }
376 
377  // Use decimal point only if the number is small. Examples:
378  // - 0.1 KiB/s
379  // - 9.9 KiB/s
380  // - 99 KiB/s
381  // - 999 KiB/s
382  // Use big enough buffer to hold e.g. a multibyte decimal point.
383  static char buf[16];
384  snprintf(buf, sizeof(buf), "%.*f %s",
385  speed > 9.9 ? 0 : 1, speed, unit[unit_index]);
386  return buf;
387 }
#define ARRAY_SIZE(a)

References ARRAY_SIZE, and snprintf.

Referenced by message_progress_update(), and progress_flush().

◆ progress_time()

static const char* progress_time ( uint64_t  mseconds)
static

Make a string indicating elapsed time. The format is either M:SS or H:MM:SS depending on if the time is an hour or more.

Definition at line 393 of file message.c.

394 {
395  // 9999 hours = 416 days
396  static char buf[sizeof("9999:59:59")];
397 
398  // 32-bit variable is enough for elapsed time (136 years).
399  uint32_t seconds = (uint32_t)(mseconds / 1000);
400 
401  // Don't show anything if the time is zero or ridiculously big.
402  if (seconds == 0 || seconds > ((9999 * 60) + 59) * 60 + 59)
403  return "";
404 
405  uint32_t minutes = seconds / 60;
406  seconds %= 60;
407 
408  if (minutes >= 60) {
409  const uint32_t hours = minutes / 60;
410  minutes %= 60;
411  snprintf(buf, sizeof(buf),
412  "%" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
413  hours, minutes, seconds);
414  } else {
415  snprintf(buf, sizeof(buf), "%" PRIu32 ":%02" PRIu32,
416  minutes, seconds);
417  }
418 
419  return buf;
420 }

References PRIu32, and snprintf.

Referenced by message_progress_update(), and progress_flush().

◆ uint32_to_optstr()

static const char* uint32_to_optstr ( uint32_t  num)
static

Convert uint32_t to a nice string for –lzma[12]=dict=SIZE.

The idea is to use KiB or MiB suffix when possible.

Definition at line 901 of file message.c.

902 {
903  static char buf[16];
904 
905  if ((num & ((UINT32_C(1) << 20) - 1)) == 0)
906  snprintf(buf, sizeof(buf), "%" PRIu32 "MiB", num >> 20);
907  else if ((num & ((UINT32_C(1) << 10) - 1)) == 0)
908  snprintf(buf, sizeof(buf), "%" PRIu32 "KiB", num >> 10);
909  else
910  snprintf(buf, sizeof(buf), "%" PRIu32, num);
911 
912  return buf;
913 }
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126

References num, PRIu32, snprintf, and UINT32_C.

Referenced by message_filters_to_str().

◆ vmessage()

static void vmessage ( enum message_verbosity  v,
const char *  fmt,
va_list  ap 
)
static

Definition at line 717 of file message.c.

718 {
719  if (v <= verbosity) {
720  signals_block();
721 
722  progress_flush(false);
723 
724  // TRANSLATORS: This is the program name in the beginning
725  // of the line in messages. Usually it becomes "xz: ".
726  // This is a translatable string because French needs
727  // a space before a colon.
728  fprintf(stderr, _("%s: "), progname);
729  vfprintf(stderr, fmt, ap);
730  fputc('\n', stderr);
731 
732  signals_unblock();
733  }
734 
735  return;
736 }

References _, progname, progress_flush(), signals_block(), signals_unblock(), v, and verbosity.

Referenced by message(), message_error(), message_fatal(), and message_warning().

Variable Documentation

◆ current_filename_printed

bool current_filename_printed = false
static

This is set to true when we have printed the current filename to stderr as part of a progress message. This variable is useful only if not updating progress automatically: if user sends many SIGINFO, SIGUSR1, or SIGALRM signals, we won't print the name of the same file multiple times.

Definition at line 41 of file message.c.

Referenced by message_filename(), message_progress_update(), and print_filename().

◆ expected_in_size

uint64_t expected_in_size
static

Expected size of the input stream is needed to show completion percentage and estimate remaining time.

Definition at line 66 of file message.c.

Referenced by message_progress_start(), progress_percentage(), and progress_remaining().

◆ filename

const char* filename
static

Filename which we will print with the verbose messages.

Definition at line 28 of file message.c.

◆ files_pos

unsigned int files_pos = 0
static

Number of the current file.

Definition at line 19 of file message.c.

Referenced by message_filename(), and print_filename().

◆ files_total

unsigned int files_total
static

Total number of input files; zero if unknown.

Definition at line 22 of file message.c.

Referenced by message_set_files(), and print_filename().

◆ first_filename_printed

bool first_filename_printed = false
static

True once the a filename has been printed to stderr as part of progress message. If automatic progress updating isn't enabled, this becomes true after the first progress message has been printed due to user sending SIGINFO, SIGUSR1, or SIGALRM. Once this variable is true, we will print an empty line before the next filename to make the output more readable.

Definition at line 35 of file message.c.

Referenced by print_filename().

◆ progress_active

bool progress_active = false
static

This is true when a progress message was printed and the cursor is still on the same line with the progress message. In that case, a newline has to be printed before any error messages.

Definition at line 54 of file message.c.

Referenced by message_progress_update(), and progress_flush().

◆ progress_automatic

bool progress_automatic
static

True if we should print progress indicator and update it automatically if also verbose >= V_VERBOSE.

Definition at line 45 of file message.c.

Referenced by message_filename(), message_init(), message_progress_start(), message_progress_update(), and progress_flush().

◆ progress_is_from_passthru

bool progress_is_from_passthru
static

This is true if we are in passthru mode (not actually compressing or decompressing) and thus cannot use lzma_get_progress(progress_strm, ...). That is, we are using coder_passthru() in coder.c.

Definition at line 62 of file message.c.

Referenced by message_progress_start(), and progress_pos().

◆ progress_needs_updating

bool progress_needs_updating = false
static

This is true when progress message printing is wanted. Using the same variable name as above to avoid some ifdefs.

Definition at line 105 of file message.c.

Referenced by message_progress_start(), and message_progress_update().

◆ progress_next_update

uint64_t progress_next_update
static

Elapsed time when the next progress message update should be done.

Definition at line 108 of file message.c.

Referenced by message_progress_start(), and message_progress_update().

◆ progress_started

bool progress_started = false
static

True if message_progress_start() has been called but message_progress_end() hasn't been called yet.

Definition at line 49 of file message.c.

Referenced by message_progress_end(), message_progress_start(), and progress_flush().

◆ progress_strm

lzma_stream* progress_strm
static

Pointer to lzma_stream used to do the encoding or decoding.

Definition at line 57 of file message.c.

Referenced by message_progress_start(), and progress_pos().

◆ verbosity