Rizin
unix-like reverse engineering framework and cli tools
message.c
Go to the documentation of this file.
1 //
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
12 
13 #include "private.h"
14 
15 #include <stdarg.h>
16 
17 
19 static unsigned int files_pos = 0;
20 
22 static unsigned int files_total;
23 
26 
28 static const char *filename;
29 
35 static bool first_filename_printed = false;
36 
41 static bool current_filename_printed = false;
42 
45 static bool progress_automatic;
46 
49 static bool progress_started = false;
50 
54 static bool progress_active = false;
55 
58 
63 
67 
68 
69 // Use alarm() and SIGALRM when they are supported. This has two minor
70 // advantages over the alternative of polling gettimeofday():
71 // - It is possible for the user to send SIGINFO, SIGUSR1, or SIGALRM to
72 // get intermediate progress information even when --verbose wasn't used
73 // or stderr is not a terminal.
74 // - alarm() + SIGALRM seems to have slightly less overhead than polling
75 // gettimeofday().
76 #ifdef SIGALRM
77 
78 const int message_progress_sigs[] = {
79  SIGALRM,
80 #ifdef SIGINFO
81  SIGINFO,
82 #endif
83 #ifdef SIGUSR1
84  SIGUSR1,
85 #endif
86  0
87 };
88 
91 static volatile sig_atomic_t progress_needs_updating = false;
92 
94 static void
95 progress_signal_handler(int sig lzma_attribute((__unused__)))
96 {
98  return;
99 }
100 
101 #else
102 
105 static bool progress_needs_updating = false;
106 
109 
110 #endif
111 
112 
113 extern void
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 }
158 
159 
160 extern void
162 {
163  if (verbosity < V_DEBUG)
164  ++verbosity;
165 
166  return;
167 }
168 
169 
170 extern void
172 {
173  if (verbosity > V_SILENT)
174  --verbosity;
175 
176  return;
177 }
178 
179 
180 extern enum message_verbosity
182 {
183  return verbosity;
184 }
185 
186 
187 extern void
189 {
190  files_total = files;
191  return;
192 }
193 
194 
199 static void
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 }
229 
230 
231 extern void
232 message_filename(const char *src_name)
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 }
246 
247 
248 extern void
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 }
287 
288 
290 static const char *
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 }
310 
311 
314 static const char *
315 progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
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 }
347 
348 
350 static const char *
351 progress_speed(uint64_t uncompressed_pos, uint64_t elapsed)
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 }
388 
389 
392 static const char *
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 }
421 
422 
425 static const char *
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 }
508 
509 
511 static void
513  uint64_t *compressed_pos, uint64_t *uncompressed_pos)
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 }
542 
543 
544 extern void
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 }
626 
627 
628 static void
629 progress_flush(bool finished)
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 }
704 
705 
706 extern void
707 message_progress_end(bool success)
708 {
710  progress_flush(success);
711  progress_started = false;
712  return;
713 }
714 
715 
716 static void
717 vmessage(enum message_verbosity v, const char *fmt, va_list ap)
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 }
737 
738 
739 extern void
740 message(enum message_verbosity v, const char *fmt, ...)
741 {
742  va_list ap;
743  va_start(ap, fmt);
744  vmessage(v, fmt, ap);
745  va_end(ap);
746  return;
747 }
748 
749 
750 extern void
751 message_warning(const char *fmt, ...)
752 {
753  va_list ap;
754  va_start(ap, fmt);
755  vmessage(V_WARNING, fmt, ap);
756  va_end(ap);
757 
759  return;
760 }
761 
762 
763 extern void
764 message_error(const char *fmt, ...)
765 {
766  va_list ap;
767  va_start(ap, fmt);
768  vmessage(V_ERROR, fmt, ap);
769  va_end(ap);
770 
772  return;
773 }
774 
775 
776 extern void
777 message_fatal(const char *fmt, ...)
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 }
786 
787 
788 extern void
790 {
791  message_fatal(_("Internal error (bug)"));
792 }
793 
794 
795 extern void
797 {
798  message_fatal(_("Cannot establish signal handlers"));
799 }
800 
801 
802 extern const char *
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 }
843 
844 
845 extern void
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 }
895 
896 
900 static const char *
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 }
914 
915 
916 extern void
918  const lzma_filter *filters, bool all_known)
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 }
1047 
1048 
1049 extern void
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 }
1060 
1061 
1062 extern void
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 }
1071 
1072 
1073 extern void
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 }
1088 
1089 
1090 extern void
1091 message_help(bool long_help)
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 ARRAY_SIZE(a)
lzma_index ** i
Definition: index.h:629
bool opt_robot
Definition: args.c:24
const char stdin_filename[]
Definition: args.c:29
#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
const lzma_allocator const uint8_t size_t uint8_t size_t * out_pos
Definition: block.h:528
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
#define PACKAGE_NAME
Definition: config.h:325
#define PACKAGE_BUGREPORT
Definition: config.h:322
#define PACKAGE_URL
Definition: config.h:334
enum operation_mode opt_mode
Definition: coder.c:24
@ MODE_COMPRESS
Definition: coder.h:14
@ MODE_LIST
Definition: coder.h:17
const lzma_filter * filters
Definition: container.h:315
uint64_t memlimit
Definition: container.h:537
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
#define LZMA_FILTER_DELTA
Filter ID.
Definition: delta.h:25
const char * v
Definition: dsignal.c:12
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 lzma_stream strm
Definition: full_flush.c:20
uint64_t hardware_memlimit_get(enum operation_mode mode)
Get the current memory usage limit for compression or decompression.
Definition: hardware.c:112
const char * filename
Definition: ioapi.h:137
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
#define PRIu32
Definition: macros.h: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 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
#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
#define lzma_attribute(attr)
Definition: lzma.h:259
@ E_WARNING
Definition: main.h:17
@ E_SUCCESS
Definition: main.h:15
assert(limit<=UINT32_MAX/2)
void message_progress_end(bool success)
Finishes the progress message if we were in verbose mode.
Definition: message.c:707
void message_help(bool long_help)
Print the help message.
Definition: message.c:1091
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
void message_verbosity_increase(void)
Increase verbosity level by one step unless it was at maximum.
Definition: message.c:161
void message_set_files(unsigned int files)
Set the total number of files to be processed.
Definition: message.c:188
static bool progress_active
Definition: message.c:54
void message_version(void)
Prints the version number to stdout and exits with exit status SUCCESS.
Definition: message.c:1074
static const char * progress_time(uint64_t mseconds)
Definition: message.c:393
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
static bool current_filename_printed
Definition: message.c:41
static bool progress_automatic
Definition: message.c:45
static bool first_filename_printed
Definition: message.c:35
static const char * progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
Definition: message.c:315
static enum message_verbosity verbosity
Verbosity level.
Definition: message.c:25
static uint64_t progress_next_update
Elapsed time when the next progress message update should be done.
Definition: message.c:108
void message_filename(const char *src_name)
Set the name of the current file and possibly print it too.
Definition: message.c:232
static bool progress_is_from_passthru
Definition: message.c:62
void message_mem_needed(enum message_verbosity v, uint64_t memusage)
Display how much memory was needed and how much the limit was.
Definition: message.c:846
void message(enum message_verbosity v, const char *fmt,...)
Definition: message.c:740
static const char * filename
Filename which we will print with the verbose messages.
Definition: message.c:28
static unsigned int files_total
Total number of input files; zero if unknown.
Definition: message.c:22
void message_init(void)
Initializes the message functions.
Definition: message.c:114
void message_signal_handler(void)
Definition: message.c:796
void message_verbosity_decrease(void)
Decrease verbosity level by one step unless it was at minimum.
Definition: message.c:171
void message_error(const char *fmt,...)
Definition: message.c:764
void message_warning(const char *fmt,...)
Definition: message.c:751
void message_bug(void)
Definition: message.c:789
static const char * progress_remaining(uint64_t in_pos, uint64_t elapsed)
Definition: message.c:426
void message_filters_show(enum message_verbosity v, const lzma_filter *filters)
Print the filter chain.
Definition: message.c:1050
static unsigned int files_pos
Number of the current file.
Definition: message.c:19
static bool progress_needs_updating
Definition: message.c:105
void message_progress_start(lzma_stream *strm, bool is_passthru, uint64_t in_size)
Start progress info handling.
Definition: message.c:249
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
void message_try_help(void)
Print a message that user should try –help.
Definition: message.c:1063
void message_progress_update(void)
Definition: message.c:545
const char * message_strm(lzma_ret code)
Convert lzma_ret to a string.
Definition: message.c:803
static bool progress_started
Definition: message.c:49
static void print_filename(void)
Definition: message.c:200
static void vmessage(enum message_verbosity v, const char *fmt, va_list ap)
Definition: message.c:717
void message_fatal(const char *fmt,...)
Definition: message.c:777
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
static void progress_flush(bool finished)
Definition: message.c:629
enum message_verbosity message_verbosity_get(void)
Get the current verbosity level.
Definition: message.c:181
const int message_progress_sigs[]
Signals used for progress message handling.
message_verbosity
Verbosity levels.
Definition: message.h:14
@ V_DEBUG
Very verbose.
Definition: message.h:19
@ V_WARNING
Errors and warnings.
Definition: message.h:17
@ V_VERBOSE
Errors, warnings, and verbose statistics.
Definition: message.h:18
@ V_ERROR
Only error messages.
Definition: message.h:16
@ V_SILENT
No messages.
Definition: message.h:15
#define FILTERS_STR_SIZE
Buffer size for message_filters_to_str()
Definition: message.h:94
uint64_t mytime_get_elapsed(void)
Get the number of milliseconds since the operation started.
Definition: mytime.c:59
string FILE
Definition: benchmark.py:21
#define _(String)
Definition: opintl.h:53
unsigned int uint32_t
Definition: sftypes.h:29
#define ENOMEM
Definition: sftypes.h:122
unsigned long uint64_t
Definition: sftypes.h:28
void signals_unblock(void)
Unblock the signals blocked by signals_block().
Definition: signals.c:135
void signals_block(void)
Definition: signals.c:120
#define UINT32_C(val)
#define UINT64_MAX
#define UINT64_C(val)
Definition: inftree9.h:24
Definition: gzappend.c:170
Filter options.
Definition: filter.h:43
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
Passing data to and from liblzma.
Definition: base.h:485
uint64_t total_in
Definition: base.h:488
uint64_t total_out
Definition: base.h:492
double percentage
Definition: main.c:10
int pos
Definition: main.c:11
void set_exit_status(enum exit_status_type new_status)
Definition: main.c:31
Common includes, definitions, and prototypes.
#define STDERR_FILENO
Definition: private.h:45
const char * uint64_to_str(uint64_t value, uint32_t slot)
Convert uint64_t to a string.
Definition: util.c:171
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
void my_snprintf(char **pos, size_t *left, const char *fmt,...)
Definition: util.c:239
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
@ E_ERROR
Definition: transport.h:23
#define tuklib_exit
Definition: tuklib_exit.h:20
#define tuklib_mbstr_fw
Definition: tuklib_mbstr.h:45
#define progname
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
Definition: vli.h:39
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ 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
#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
nicestr_unit
Definition: util.h:64
@ NICESTR_MIB
Definition: util.h:67
@ NICESTR_B
Definition: util.h:65
@ NICESTR_TIB
Definition: util.h:69