laag-xz 5.2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (393) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +57 -0
  3. data/LICENSE.txt +65 -0
  4. data/README.org +34 -0
  5. data/ext/laag/xz/extconf.rb +21 -0
  6. data/laag-xz.gemspec +20 -0
  7. data/lib/laag/xz.rb +29 -0
  8. data/vendor/git.tukaani.org/xz/.gitignore +66 -0
  9. data/vendor/git.tukaani.org/xz/AUTHORS +27 -0
  10. data/vendor/git.tukaani.org/xz/COPYING +65 -0
  11. data/vendor/git.tukaani.org/xz/COPYING.GPLv2 +339 -0
  12. data/vendor/git.tukaani.org/xz/COPYING.GPLv3 +674 -0
  13. data/vendor/git.tukaani.org/xz/COPYING.LGPLv2.1 +502 -0
  14. data/vendor/git.tukaani.org/xz/ChangeLog +7 -0
  15. data/vendor/git.tukaani.org/xz/Doxyfile.in +1234 -0
  16. data/vendor/git.tukaani.org/xz/INSTALL +618 -0
  17. data/vendor/git.tukaani.org/xz/INSTALL.generic +365 -0
  18. data/vendor/git.tukaani.org/xz/Makefile.am +110 -0
  19. data/vendor/git.tukaani.org/xz/NEWS +571 -0
  20. data/vendor/git.tukaani.org/xz/PACKAGERS +231 -0
  21. data/vendor/git.tukaani.org/xz/README +308 -0
  22. data/vendor/git.tukaani.org/xz/THANKS +124 -0
  23. data/vendor/git.tukaani.org/xz/TODO +111 -0
  24. data/vendor/git.tukaani.org/xz/autogen.sh +22 -0
  25. data/vendor/git.tukaani.org/xz/build-aux/manconv.sh +58 -0
  26. data/vendor/git.tukaani.org/xz/build-aux/version.sh +24 -0
  27. data/vendor/git.tukaani.org/xz/configure.ac +900 -0
  28. data/vendor/git.tukaani.org/xz/debug/Makefile.am +30 -0
  29. data/vendor/git.tukaani.org/xz/debug/README +17 -0
  30. data/vendor/git.tukaani.org/xz/debug/crc32.c +39 -0
  31. data/vendor/git.tukaani.org/xz/debug/full_flush.c +103 -0
  32. data/vendor/git.tukaani.org/xz/debug/hex2bin.c +53 -0
  33. data/vendor/git.tukaani.org/xz/debug/known_sizes.c +129 -0
  34. data/vendor/git.tukaani.org/xz/debug/memusage.c +51 -0
  35. data/vendor/git.tukaani.org/xz/debug/repeat.c +36 -0
  36. data/vendor/git.tukaani.org/xz/debug/sync_flush.c +125 -0
  37. data/vendor/git.tukaani.org/xz/debug/translation.bash +100 -0
  38. data/vendor/git.tukaani.org/xz/doc/examples/00_README.txt +31 -0
  39. data/vendor/git.tukaani.org/xz/doc/examples/01_compress_easy.c +297 -0
  40. data/vendor/git.tukaani.org/xz/doc/examples/02_decompress.c +287 -0
  41. data/vendor/git.tukaani.org/xz/doc/examples/03_compress_custom.c +193 -0
  42. data/vendor/git.tukaani.org/xz/doc/examples/04_compress_easy_mt.c +206 -0
  43. data/vendor/git.tukaani.org/xz/doc/examples/Makefile +24 -0
  44. data/vendor/git.tukaani.org/xz/doc/examples_old/xz_pipe_comp.c +127 -0
  45. data/vendor/git.tukaani.org/xz/doc/examples_old/xz_pipe_decomp.c +123 -0
  46. data/vendor/git.tukaani.org/xz/doc/faq.txt +224 -0
  47. data/vendor/git.tukaani.org/xz/doc/history.txt +150 -0
  48. data/vendor/git.tukaani.org/xz/doc/lzma-file-format.txt +166 -0
  49. data/vendor/git.tukaani.org/xz/doc/xz-file-format.txt +1150 -0
  50. data/vendor/git.tukaani.org/xz/dos/INSTALL.txt +79 -0
  51. data/vendor/git.tukaani.org/xz/dos/Makefile +147 -0
  52. data/vendor/git.tukaani.org/xz/dos/README.txt +123 -0
  53. data/vendor/git.tukaani.org/xz/dos/config.h +136 -0
  54. data/vendor/git.tukaani.org/xz/extra/7z2lzma/7z2lzma.bash +115 -0
  55. data/vendor/git.tukaani.org/xz/extra/scanlzma/scanlzma.c +88 -0
  56. data/vendor/git.tukaani.org/xz/lib/Makefile.am +32 -0
  57. data/vendor/git.tukaani.org/xz/lib/getopt.c +1197 -0
  58. data/vendor/git.tukaani.org/xz/lib/getopt.in.h +226 -0
  59. data/vendor/git.tukaani.org/xz/lib/getopt1.c +171 -0
  60. data/vendor/git.tukaani.org/xz/lib/getopt_int.h +131 -0
  61. data/vendor/git.tukaani.org/xz/m4/.gitignore +38 -0
  62. data/vendor/git.tukaani.org/xz/m4/ax_check_capsicum.m4 +85 -0
  63. data/vendor/git.tukaani.org/xz/m4/ax_pthread.m4 +332 -0
  64. data/vendor/git.tukaani.org/xz/m4/getopt.m4 +71 -0
  65. data/vendor/git.tukaani.org/xz/m4/posix-shell.m4 +63 -0
  66. data/vendor/git.tukaani.org/xz/m4/tuklib_common.m4 +22 -0
  67. data/vendor/git.tukaani.org/xz/m4/tuklib_cpucores.m4 +176 -0
  68. data/vendor/git.tukaani.org/xz/m4/tuklib_integer.m4 +74 -0
  69. data/vendor/git.tukaani.org/xz/m4/tuklib_mbstr.m4 +30 -0
  70. data/vendor/git.tukaani.org/xz/m4/tuklib_physmem.m4 +212 -0
  71. data/vendor/git.tukaani.org/xz/m4/tuklib_progname.m4 +25 -0
  72. data/vendor/git.tukaani.org/xz/macosx/build.sh +113 -0
  73. data/vendor/git.tukaani.org/xz/po/.gitignore +31 -0
  74. data/vendor/git.tukaani.org/xz/po/LINGUAS +6 -0
  75. data/vendor/git.tukaani.org/xz/po/Makevars +46 -0
  76. data/vendor/git.tukaani.org/xz/po/POTFILES.in +13 -0
  77. data/vendor/git.tukaani.org/xz/po/cs.po +949 -0
  78. data/vendor/git.tukaani.org/xz/po/de.po +993 -0
  79. data/vendor/git.tukaani.org/xz/po/fr.po +978 -0
  80. data/vendor/git.tukaani.org/xz/po/it.po +1067 -0
  81. data/vendor/git.tukaani.org/xz/po/pl.po +968 -0
  82. data/vendor/git.tukaani.org/xz/po/vi.po +1039 -0
  83. data/vendor/git.tukaani.org/xz/src/Makefile.am +42 -0
  84. data/vendor/git.tukaani.org/xz/src/common/common_w32res.rc +50 -0
  85. data/vendor/git.tukaani.org/xz/src/common/mythread.h +521 -0
  86. data/vendor/git.tukaani.org/xz/src/common/sysdefs.h +202 -0
  87. data/vendor/git.tukaani.org/xz/src/common/tuklib_common.h +71 -0
  88. data/vendor/git.tukaani.org/xz/src/common/tuklib_config.h +7 -0
  89. data/vendor/git.tukaani.org/xz/src/common/tuklib_cpucores.c +100 -0
  90. data/vendor/git.tukaani.org/xz/src/common/tuklib_cpucores.h +23 -0
  91. data/vendor/git.tukaani.org/xz/src/common/tuklib_exit.c +57 -0
  92. data/vendor/git.tukaani.org/xz/src/common/tuklib_exit.h +25 -0
  93. data/vendor/git.tukaani.org/xz/src/common/tuklib_gettext.h +44 -0
  94. data/vendor/git.tukaani.org/xz/src/common/tuklib_integer.h +534 -0
  95. data/vendor/git.tukaani.org/xz/src/common/tuklib_mbstr.h +66 -0
  96. data/vendor/git.tukaani.org/xz/src/common/tuklib_mbstr_fw.c +31 -0
  97. data/vendor/git.tukaani.org/xz/src/common/tuklib_mbstr_width.c +64 -0
  98. data/vendor/git.tukaani.org/xz/src/common/tuklib_open_stdxxx.c +57 -0
  99. data/vendor/git.tukaani.org/xz/src/common/tuklib_open_stdxxx.h +23 -0
  100. data/vendor/git.tukaani.org/xz/src/common/tuklib_physmem.c +216 -0
  101. data/vendor/git.tukaani.org/xz/src/common/tuklib_physmem.h +28 -0
  102. data/vendor/git.tukaani.org/xz/src/common/tuklib_progname.c +50 -0
  103. data/vendor/git.tukaani.org/xz/src/common/tuklib_progname.h +32 -0
  104. data/vendor/git.tukaani.org/xz/src/liblzma/Makefile.am +122 -0
  105. data/vendor/git.tukaani.org/xz/src/liblzma/api/Makefile.am +23 -0
  106. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma.h +325 -0
  107. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/base.h +659 -0
  108. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/bcj.h +90 -0
  109. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/block.h +581 -0
  110. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/check.h +150 -0
  111. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/container.h +632 -0
  112. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/delta.h +77 -0
  113. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/filter.h +425 -0
  114. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/hardware.h +64 -0
  115. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/index.h +686 -0
  116. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/index_hash.h +107 -0
  117. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/lzma12.h +420 -0
  118. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/stream_flags.h +223 -0
  119. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/version.h +121 -0
  120. data/vendor/git.tukaani.org/xz/src/liblzma/api/lzma/vli.h +166 -0
  121. data/vendor/git.tukaani.org/xz/src/liblzma/check/Makefile.inc +53 -0
  122. data/vendor/git.tukaani.org/xz/src/liblzma/check/check.c +174 -0
  123. data/vendor/git.tukaani.org/xz/src/liblzma/check/check.h +172 -0
  124. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_fast.c +82 -0
  125. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_small.c +61 -0
  126. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_table.c +19 -0
  127. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_table_be.h +525 -0
  128. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_table_le.h +525 -0
  129. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_tablegen.c +117 -0
  130. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc32_x86.S +304 -0
  131. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_fast.c +72 -0
  132. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_small.c +53 -0
  133. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_table.c +19 -0
  134. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_table_be.h +521 -0
  135. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_table_le.h +521 -0
  136. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_tablegen.c +88 -0
  137. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc64_x86.S +287 -0
  138. data/vendor/git.tukaani.org/xz/src/liblzma/check/crc_macros.h +30 -0
  139. data/vendor/git.tukaani.org/xz/src/liblzma/check/sha256.c +196 -0
  140. data/vendor/git.tukaani.org/xz/src/liblzma/common/Makefile.inc +79 -0
  141. data/vendor/git.tukaani.org/xz/src/liblzma/common/alone_decoder.c +243 -0
  142. data/vendor/git.tukaani.org/xz/src/liblzma/common/alone_decoder.h +23 -0
  143. data/vendor/git.tukaani.org/xz/src/liblzma/common/alone_encoder.c +163 -0
  144. data/vendor/git.tukaani.org/xz/src/liblzma/common/auto_decoder.c +195 -0
  145. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_buffer_decoder.c +80 -0
  146. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_buffer_encoder.c +337 -0
  147. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_buffer_encoder.h +24 -0
  148. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_decoder.c +257 -0
  149. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_decoder.h +22 -0
  150. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_encoder.c +223 -0
  151. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_encoder.h +47 -0
  152. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_header_decoder.c +124 -0
  153. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_header_encoder.c +132 -0
  154. data/vendor/git.tukaani.org/xz/src/liblzma/common/block_util.c +90 -0
  155. data/vendor/git.tukaani.org/xz/src/liblzma/common/common.c +445 -0
  156. data/vendor/git.tukaani.org/xz/src/liblzma/common/common.h +314 -0
  157. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_buffer_encoder.c +27 -0
  158. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_decoder_memusage.c +24 -0
  159. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_encoder.c +24 -0
  160. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_encoder_memusage.c +24 -0
  161. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_preset.c +27 -0
  162. data/vendor/git.tukaani.org/xz/src/liblzma/common/easy_preset.h +32 -0
  163. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_buffer_decoder.c +88 -0
  164. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_buffer_encoder.c +55 -0
  165. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_common.c +337 -0
  166. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_common.h +48 -0
  167. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_decoder.c +184 -0
  168. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_decoder.h +23 -0
  169. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_encoder.c +286 -0
  170. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_encoder.h +27 -0
  171. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_flags_decoder.c +46 -0
  172. data/vendor/git.tukaani.org/xz/src/liblzma/common/filter_flags_encoder.c +56 -0
  173. data/vendor/git.tukaani.org/xz/src/liblzma/common/hardware_cputhreads.c +22 -0
  174. data/vendor/git.tukaani.org/xz/src/liblzma/common/hardware_physmem.c +25 -0
  175. data/vendor/git.tukaani.org/xz/src/liblzma/common/index.c +1250 -0
  176. data/vendor/git.tukaani.org/xz/src/liblzma/common/index.h +73 -0
  177. data/vendor/git.tukaani.org/xz/src/liblzma/common/index_decoder.c +352 -0
  178. data/vendor/git.tukaani.org/xz/src/liblzma/common/index_encoder.c +256 -0
  179. data/vendor/git.tukaani.org/xz/src/liblzma/common/index_encoder.h +23 -0
  180. data/vendor/git.tukaani.org/xz/src/liblzma/common/index_hash.c +334 -0
  181. data/vendor/git.tukaani.org/xz/src/liblzma/common/memcmplen.h +175 -0
  182. data/vendor/git.tukaani.org/xz/src/liblzma/common/outqueue.c +184 -0
  183. data/vendor/git.tukaani.org/xz/src/liblzma/common/outqueue.h +156 -0
  184. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_buffer_decoder.c +91 -0
  185. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_buffer_encoder.c +141 -0
  186. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_decoder.c +467 -0
  187. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_decoder.h +22 -0
  188. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_encoder.c +340 -0
  189. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_encoder_mt.c +1143 -0
  190. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_flags_common.c +47 -0
  191. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_flags_common.h +33 -0
  192. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_flags_decoder.c +82 -0
  193. data/vendor/git.tukaani.org/xz/src/liblzma/common/stream_flags_encoder.c +86 -0
  194. data/vendor/git.tukaani.org/xz/src/liblzma/common/vli_decoder.c +86 -0
  195. data/vendor/git.tukaani.org/xz/src/liblzma/common/vli_encoder.c +69 -0
  196. data/vendor/git.tukaani.org/xz/src/liblzma/common/vli_size.c +30 -0
  197. data/vendor/git.tukaani.org/xz/src/liblzma/delta/Makefile.inc +23 -0
  198. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_common.c +73 -0
  199. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_common.h +20 -0
  200. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_decoder.c +78 -0
  201. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_decoder.h +26 -0
  202. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_encoder.c +125 -0
  203. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_encoder.h +24 -0
  204. data/vendor/git.tukaani.org/xz/src/liblzma/delta/delta_private.h +37 -0
  205. data/vendor/git.tukaani.org/xz/src/liblzma/liblzma.map +108 -0
  206. data/vendor/git.tukaani.org/xz/src/liblzma/liblzma.pc.in +19 -0
  207. data/vendor/git.tukaani.org/xz/src/liblzma/liblzma_w32res.rc +12 -0
  208. data/vendor/git.tukaani.org/xz/src/liblzma/lz/Makefile.inc +22 -0
  209. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_decoder.c +306 -0
  210. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_decoder.h +234 -0
  211. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_encoder.c +616 -0
  212. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_encoder.h +327 -0
  213. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_encoder_hash.h +108 -0
  214. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_encoder_hash_table.h +68 -0
  215. data/vendor/git.tukaani.org/xz/src/liblzma/lz/lz_encoder_mf.c +744 -0
  216. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/Makefile.inc +47 -0
  217. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/fastpos.h +141 -0
  218. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/fastpos_table.c +519 -0
  219. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/fastpos_tablegen.c +56 -0
  220. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma2_decoder.c +310 -0
  221. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma2_decoder.h +29 -0
  222. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma2_encoder.c +410 -0
  223. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma2_encoder.h +43 -0
  224. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_common.h +224 -0
  225. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_decoder.c +1064 -0
  226. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_decoder.h +53 -0
  227. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder.c +677 -0
  228. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder.h +58 -0
  229. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder_optimum_fast.c +170 -0
  230. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder_optimum_normal.c +855 -0
  231. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder_presets.c +64 -0
  232. data/vendor/git.tukaani.org/xz/src/liblzma/lzma/lzma_encoder_private.h +148 -0
  233. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/Makefile.inc +21 -0
  234. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/price.h +92 -0
  235. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/price_table.c +22 -0
  236. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/price_tablegen.c +87 -0
  237. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/range_common.h +71 -0
  238. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/range_decoder.h +185 -0
  239. data/vendor/git.tukaani.org/xz/src/liblzma/rangecoder/range_encoder.h +231 -0
  240. data/vendor/git.tukaani.org/xz/src/liblzma/simple/Makefile.inc +47 -0
  241. data/vendor/git.tukaani.org/xz/src/liblzma/simple/arm.c +71 -0
  242. data/vendor/git.tukaani.org/xz/src/liblzma/simple/armthumb.c +76 -0
  243. data/vendor/git.tukaani.org/xz/src/liblzma/simple/ia64.c +112 -0
  244. data/vendor/git.tukaani.org/xz/src/liblzma/simple/powerpc.c +75 -0
  245. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_coder.c +282 -0
  246. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_coder.h +72 -0
  247. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_decoder.c +40 -0
  248. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_decoder.h +22 -0
  249. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_encoder.c +38 -0
  250. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_encoder.h +23 -0
  251. data/vendor/git.tukaani.org/xz/src/liblzma/simple/simple_private.h +74 -0
  252. data/vendor/git.tukaani.org/xz/src/liblzma/simple/sparc.c +83 -0
  253. data/vendor/git.tukaani.org/xz/src/liblzma/simple/x86.c +159 -0
  254. data/vendor/git.tukaani.org/xz/src/liblzma/validate_map.sh +68 -0
  255. data/vendor/git.tukaani.org/xz/src/lzmainfo/Makefile.am +39 -0
  256. data/vendor/git.tukaani.org/xz/src/lzmainfo/lzmainfo.1 +60 -0
  257. data/vendor/git.tukaani.org/xz/src/lzmainfo/lzmainfo.c +219 -0
  258. data/vendor/git.tukaani.org/xz/src/lzmainfo/lzmainfo_w32res.rc +12 -0
  259. data/vendor/git.tukaani.org/xz/src/scripts/Makefile.am +55 -0
  260. data/vendor/git.tukaani.org/xz/src/scripts/xzdiff.1 +77 -0
  261. data/vendor/git.tukaani.org/xz/src/scripts/xzdiff.in +200 -0
  262. data/vendor/git.tukaani.org/xz/src/scripts/xzgrep.1 +98 -0
  263. data/vendor/git.tukaani.org/xz/src/scripts/xzgrep.in +215 -0
  264. data/vendor/git.tukaani.org/xz/src/scripts/xzless.1 +69 -0
  265. data/vendor/git.tukaani.org/xz/src/scripts/xzless.in +58 -0
  266. data/vendor/git.tukaani.org/xz/src/scripts/xzmore.1 +55 -0
  267. data/vendor/git.tukaani.org/xz/src/scripts/xzmore.in +78 -0
  268. data/vendor/git.tukaani.org/xz/src/xz/Makefile.am +111 -0
  269. data/vendor/git.tukaani.org/xz/src/xz/args.c +700 -0
  270. data/vendor/git.tukaani.org/xz/src/xz/args.h +44 -0
  271. data/vendor/git.tukaani.org/xz/src/xz/coder.c +936 -0
  272. data/vendor/git.tukaani.org/xz/src/xz/coder.h +76 -0
  273. data/vendor/git.tukaani.org/xz/src/xz/file_io.c +1300 -0
  274. data/vendor/git.tukaani.org/xz/src/xz/file_io.h +156 -0
  275. data/vendor/git.tukaani.org/xz/src/xz/hardware.c +150 -0
  276. data/vendor/git.tukaani.org/xz/src/xz/hardware.h +37 -0
  277. data/vendor/git.tukaani.org/xz/src/xz/list.c +1192 -0
  278. data/vendor/git.tukaani.org/xz/src/xz/list.h +18 -0
  279. data/vendor/git.tukaani.org/xz/src/xz/main.c +330 -0
  280. data/vendor/git.tukaani.org/xz/src/xz/main.h +30 -0
  281. data/vendor/git.tukaani.org/xz/src/xz/message.c +1258 -0
  282. data/vendor/git.tukaani.org/xz/src/xz/message.h +167 -0
  283. data/vendor/git.tukaani.org/xz/src/xz/mytime.c +89 -0
  284. data/vendor/git.tukaani.org/xz/src/xz/mytime.h +47 -0
  285. data/vendor/git.tukaani.org/xz/src/xz/options.c +363 -0
  286. data/vendor/git.tukaani.org/xz/src/xz/options.h +31 -0
  287. data/vendor/git.tukaani.org/xz/src/xz/private.h +66 -0
  288. data/vendor/git.tukaani.org/xz/src/xz/signals.c +209 -0
  289. data/vendor/git.tukaani.org/xz/src/xz/signals.h +43 -0
  290. data/vendor/git.tukaani.org/xz/src/xz/suffix.c +399 -0
  291. data/vendor/git.tukaani.org/xz/src/xz/suffix.h +28 -0
  292. data/vendor/git.tukaani.org/xz/src/xz/util.c +288 -0
  293. data/vendor/git.tukaani.org/xz/src/xz/util.h +123 -0
  294. data/vendor/git.tukaani.org/xz/src/xz/xz.1 +2786 -0
  295. data/vendor/git.tukaani.org/xz/src/xz/xz_w32res.rc +12 -0
  296. data/vendor/git.tukaani.org/xz/src/xzdec/Makefile.am +82 -0
  297. data/vendor/git.tukaani.org/xz/src/xzdec/lzmadec_w32res.rc +12 -0
  298. data/vendor/git.tukaani.org/xz/src/xzdec/xzdec.1 +146 -0
  299. data/vendor/git.tukaani.org/xz/src/xzdec/xzdec.c +323 -0
  300. data/vendor/git.tukaani.org/xz/src/xzdec/xzdec_w32res.rc +12 -0
  301. data/vendor/git.tukaani.org/xz/tests/Makefile.am +57 -0
  302. data/vendor/git.tukaani.org/xz/tests/bcj_test.c +65 -0
  303. data/vendor/git.tukaani.org/xz/tests/compress_prepared_bcj_sparc +0 -0
  304. data/vendor/git.tukaani.org/xz/tests/compress_prepared_bcj_x86 +0 -0
  305. data/vendor/git.tukaani.org/xz/tests/create_compress_files.c +158 -0
  306. data/vendor/git.tukaani.org/xz/tests/files/README +240 -0
  307. data/vendor/git.tukaani.org/xz/tests/files/bad-0-backward_size.xz +0 -0
  308. data/vendor/git.tukaani.org/xz/tests/files/bad-0-empty-truncated.xz +0 -0
  309. data/vendor/git.tukaani.org/xz/tests/files/bad-0-footer_magic.xz +0 -0
  310. data/vendor/git.tukaani.org/xz/tests/files/bad-0-header_magic.xz +0 -0
  311. data/vendor/git.tukaani.org/xz/tests/files/bad-0-nonempty_index.xz +0 -0
  312. data/vendor/git.tukaani.org/xz/tests/files/bad-0cat-alone.xz +0 -0
  313. data/vendor/git.tukaani.org/xz/tests/files/bad-0cat-header_magic.xz +0 -0
  314. data/vendor/git.tukaani.org/xz/tests/files/bad-0catpad-empty.xz +0 -0
  315. data/vendor/git.tukaani.org/xz/tests/files/bad-0pad-empty.xz +0 -0
  316. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-1.xz +0 -0
  317. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-2.xz +0 -0
  318. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-3.xz +0 -0
  319. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-4.xz +0 -0
  320. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-5.xz +0 -0
  321. data/vendor/git.tukaani.org/xz/tests/files/bad-1-block_header-6.xz +0 -0
  322. data/vendor/git.tukaani.org/xz/tests/files/bad-1-check-crc32.xz +0 -0
  323. data/vendor/git.tukaani.org/xz/tests/files/bad-1-check-crc64.xz +0 -0
  324. data/vendor/git.tukaani.org/xz/tests/files/bad-1-check-sha256.xz +0 -0
  325. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-1.xz +0 -0
  326. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-2.xz +0 -0
  327. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-3.xz +0 -0
  328. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-4.xz +0 -0
  329. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-5.xz +0 -0
  330. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-6.xz +0 -0
  331. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-7.xz +0 -0
  332. data/vendor/git.tukaani.org/xz/tests/files/bad-1-lzma2-8.xz +0 -0
  333. data/vendor/git.tukaani.org/xz/tests/files/bad-1-stream_flags-1.xz +0 -0
  334. data/vendor/git.tukaani.org/xz/tests/files/bad-1-stream_flags-2.xz +0 -0
  335. data/vendor/git.tukaani.org/xz/tests/files/bad-1-stream_flags-3.xz +0 -0
  336. data/vendor/git.tukaani.org/xz/tests/files/bad-1-vli-1.xz +0 -0
  337. data/vendor/git.tukaani.org/xz/tests/files/bad-1-vli-2.xz +0 -0
  338. data/vendor/git.tukaani.org/xz/tests/files/bad-2-compressed_data_padding.xz +0 -0
  339. data/vendor/git.tukaani.org/xz/tests/files/bad-2-index-1.xz +0 -0
  340. data/vendor/git.tukaani.org/xz/tests/files/bad-2-index-2.xz +0 -0
  341. data/vendor/git.tukaani.org/xz/tests/files/bad-2-index-3.xz +0 -0
  342. data/vendor/git.tukaani.org/xz/tests/files/bad-2-index-4.xz +0 -0
  343. data/vendor/git.tukaani.org/xz/tests/files/bad-2-index-5.xz +0 -0
  344. data/vendor/git.tukaani.org/xz/tests/files/good-0-empty.xz +0 -0
  345. data/vendor/git.tukaani.org/xz/tests/files/good-0cat-empty.xz +0 -0
  346. data/vendor/git.tukaani.org/xz/tests/files/good-0catpad-empty.xz +0 -0
  347. data/vendor/git.tukaani.org/xz/tests/files/good-0pad-empty.xz +0 -0
  348. data/vendor/git.tukaani.org/xz/tests/files/good-1-3delta-lzma2.xz +0 -0
  349. data/vendor/git.tukaani.org/xz/tests/files/good-1-block_header-1.xz +0 -0
  350. data/vendor/git.tukaani.org/xz/tests/files/good-1-block_header-2.xz +0 -0
  351. data/vendor/git.tukaani.org/xz/tests/files/good-1-block_header-3.xz +0 -0
  352. data/vendor/git.tukaani.org/xz/tests/files/good-1-check-crc32.xz +0 -0
  353. data/vendor/git.tukaani.org/xz/tests/files/good-1-check-crc64.xz +0 -0
  354. data/vendor/git.tukaani.org/xz/tests/files/good-1-check-none.xz +0 -0
  355. data/vendor/git.tukaani.org/xz/tests/files/good-1-check-sha256.xz +0 -0
  356. data/vendor/git.tukaani.org/xz/tests/files/good-1-delta-lzma2.tiff.xz +0 -0
  357. data/vendor/git.tukaani.org/xz/tests/files/good-1-lzma2-1.xz +0 -0
  358. data/vendor/git.tukaani.org/xz/tests/files/good-1-lzma2-2.xz +0 -0
  359. data/vendor/git.tukaani.org/xz/tests/files/good-1-lzma2-3.xz +0 -0
  360. data/vendor/git.tukaani.org/xz/tests/files/good-1-lzma2-4.xz +0 -0
  361. data/vendor/git.tukaani.org/xz/tests/files/good-1-lzma2-5.xz +0 -0
  362. data/vendor/git.tukaani.org/xz/tests/files/good-1-sparc-lzma2.xz +0 -0
  363. data/vendor/git.tukaani.org/xz/tests/files/good-1-x86-lzma2.xz +0 -0
  364. data/vendor/git.tukaani.org/xz/tests/files/good-2-lzma2.xz +0 -0
  365. data/vendor/git.tukaani.org/xz/tests/files/unsupported-block_header.xz +0 -0
  366. data/vendor/git.tukaani.org/xz/tests/files/unsupported-check.xz +0 -0
  367. data/vendor/git.tukaani.org/xz/tests/files/unsupported-filter_flags-1.xz +0 -0
  368. data/vendor/git.tukaani.org/xz/tests/files/unsupported-filter_flags-2.xz +0 -0
  369. data/vendor/git.tukaani.org/xz/tests/files/unsupported-filter_flags-3.xz +0 -0
  370. data/vendor/git.tukaani.org/xz/tests/test_bcj_exact_size.c +113 -0
  371. data/vendor/git.tukaani.org/xz/tests/test_block_header.c +240 -0
  372. data/vendor/git.tukaani.org/xz/tests/test_check.c +83 -0
  373. data/vendor/git.tukaani.org/xz/tests/test_compress.sh +142 -0
  374. data/vendor/git.tukaani.org/xz/tests/test_files.sh +57 -0
  375. data/vendor/git.tukaani.org/xz/tests/test_filter_flags.c +258 -0
  376. data/vendor/git.tukaani.org/xz/tests/test_index.c +689 -0
  377. data/vendor/git.tukaani.org/xz/tests/test_scripts.sh +76 -0
  378. data/vendor/git.tukaani.org/xz/tests/test_stream_flags.c +180 -0
  379. data/vendor/git.tukaani.org/xz/tests/tests.h +124 -0
  380. data/vendor/git.tukaani.org/xz/tests/xzgrep_expected_output +39 -0
  381. data/vendor/git.tukaani.org/xz/windows/INSTALL-MSVC.txt +47 -0
  382. data/vendor/git.tukaani.org/xz/windows/INSTALL-MinGW.txt +138 -0
  383. data/vendor/git.tukaani.org/xz/windows/README-Windows.txt +122 -0
  384. data/vendor/git.tukaani.org/xz/windows/build.bash +203 -0
  385. data/vendor/git.tukaani.org/xz/windows/vs2013/config.h +148 -0
  386. data/vendor/git.tukaani.org/xz/windows/vs2013/liblzma.vcxproj +354 -0
  387. data/vendor/git.tukaani.org/xz/windows/vs2013/liblzma_dll.vcxproj +383 -0
  388. data/vendor/git.tukaani.org/xz/windows/vs2013/xz_win.sln +48 -0
  389. data/vendor/git.tukaani.org/xz/windows/vs2017/config.h +148 -0
  390. data/vendor/git.tukaani.org/xz/windows/vs2017/liblzma.vcxproj +355 -0
  391. data/vendor/git.tukaani.org/xz/windows/vs2017/liblzma_dll.vcxproj +384 -0
  392. data/vendor/git.tukaani.org/xz/windows/vs2017/xz_win.sln +48 -0
  393. metadata +457 -0
@@ -0,0 +1,18 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file list.h
4
+ /// \brief List information about .xz files
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
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ /// \brief List information about the given .xz file
14
+ extern void list_file(const char *filename);
15
+
16
+
17
+ /// \brief Show the totals after all files have been listed
18
+ extern void list_totals(void);
@@ -0,0 +1,330 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file main.c
4
+ /// \brief main()
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
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ #include "private.h"
14
+ #include <ctype.h>
15
+
16
+ /// Exit status to use. This can be changed with set_exit_status().
17
+ static enum exit_status_type exit_status = E_SUCCESS;
18
+
19
+ #if defined(_WIN32) && !defined(__CYGWIN__)
20
+ /// exit_status has to be protected with a critical section due to
21
+ /// how "signal handling" is done on Windows. See signals.c for details.
22
+ static CRITICAL_SECTION exit_status_cs;
23
+ #endif
24
+
25
+ /// True if --no-warn is specified. When this is true, we don't set
26
+ /// the exit status to E_WARNING when something worth a warning happens.
27
+ static bool no_warn = false;
28
+
29
+
30
+ extern void
31
+ set_exit_status(enum exit_status_type new_status)
32
+ {
33
+ assert(new_status == E_WARNING || new_status == E_ERROR);
34
+
35
+ #if defined(_WIN32) && !defined(__CYGWIN__)
36
+ EnterCriticalSection(&exit_status_cs);
37
+ #endif
38
+
39
+ if (exit_status != E_ERROR)
40
+ exit_status = new_status;
41
+
42
+ #if defined(_WIN32) && !defined(__CYGWIN__)
43
+ LeaveCriticalSection(&exit_status_cs);
44
+ #endif
45
+
46
+ return;
47
+ }
48
+
49
+
50
+ extern void
51
+ set_exit_no_warn(void)
52
+ {
53
+ no_warn = true;
54
+ return;
55
+ }
56
+
57
+
58
+ static const char *
59
+ read_name(const args_info *args)
60
+ {
61
+ // FIXME: Maybe we should have some kind of memory usage limit here
62
+ // like the tool has for the actual compression and decompression.
63
+ // Giving some huge text file with --files0 makes us to read the
64
+ // whole file in RAM.
65
+ static char *name = NULL;
66
+ static size_t size = 256;
67
+
68
+ // Allocate the initial buffer. This is never freed, since after it
69
+ // is no longer needed, the program exits very soon. It is safe to
70
+ // use xmalloc() and xrealloc() in this function, because while
71
+ // executing this function, no files are open for writing, and thus
72
+ // there's no need to cleanup anything before exiting.
73
+ if (name == NULL)
74
+ name = xmalloc(size);
75
+
76
+ // Write position in name
77
+ size_t pos = 0;
78
+
79
+ // Read one character at a time into name.
80
+ while (!user_abort) {
81
+ const int c = fgetc(args->files_file);
82
+
83
+ if (ferror(args->files_file)) {
84
+ // Take care of EINTR since we have established
85
+ // the signal handlers already.
86
+ if (errno == EINTR)
87
+ continue;
88
+
89
+ message_error(_("%s: Error reading filenames: %s"),
90
+ args->files_name, strerror(errno));
91
+ return NULL;
92
+ }
93
+
94
+ if (feof(args->files_file)) {
95
+ if (pos != 0)
96
+ message_error(_("%s: Unexpected end of input "
97
+ "when reading filenames"),
98
+ args->files_name);
99
+
100
+ return NULL;
101
+ }
102
+
103
+ if (c == args->files_delim) {
104
+ // We allow consecutive newline (--files) or '\0'
105
+ // characters (--files0), and ignore such empty
106
+ // filenames.
107
+ if (pos == 0)
108
+ continue;
109
+
110
+ // A non-empty name was read. Terminate it with '\0'
111
+ // and return it.
112
+ name[pos] = '\0';
113
+ return name;
114
+ }
115
+
116
+ if (c == '\0') {
117
+ // A null character was found when using --files,
118
+ // which expects plain text input separated with
119
+ // newlines.
120
+ message_error(_("%s: Null character found when "
121
+ "reading filenames; maybe you meant "
122
+ "to use `--files0' instead "
123
+ "of `--files'?"), args->files_name);
124
+ return NULL;
125
+ }
126
+
127
+ name[pos++] = c;
128
+
129
+ // Allocate more memory if needed. There must always be space
130
+ // at least for one character to allow terminating the string
131
+ // with '\0'.
132
+ if (pos == size) {
133
+ size *= 2;
134
+ name = xrealloc(name, size);
135
+ }
136
+ }
137
+
138
+ return NULL;
139
+ }
140
+
141
+
142
+ int
143
+ main(int argc, char **argv)
144
+ {
145
+ #if defined(_WIN32) && !defined(__CYGWIN__)
146
+ InitializeCriticalSection(&exit_status_cs);
147
+ #endif
148
+
149
+ // Set up the progname variable.
150
+ tuklib_progname_init(argv);
151
+
152
+ // Initialize the file I/O. This makes sure that
153
+ // stdin, stdout, and stderr are something valid.
154
+ io_init();
155
+
156
+ // Set up the locale and message translations.
157
+ tuklib_gettext_init(PACKAGE, LOCALEDIR);
158
+
159
+ // Initialize handling of error/warning/other messages.
160
+ message_init();
161
+
162
+ // Set hardware-dependent default values. These can be overriden
163
+ // on the command line, thus this must be done before args_parse().
164
+ hardware_init();
165
+
166
+ // Parse the command line arguments and get an array of filenames.
167
+ // This doesn't return if something is wrong with the command line
168
+ // arguments. If there are no arguments, one filename ("-") is still
169
+ // returned to indicate stdin.
170
+ args_info args;
171
+ args_parse(&args, argc, argv);
172
+
173
+ if (opt_mode != MODE_LIST && opt_robot)
174
+ message_fatal(_("Compression and decompression with --robot "
175
+ "are not supported yet."));
176
+
177
+ // Tell the message handling code how many input files there are if
178
+ // we know it. This way the progress indicator can show it.
179
+ if (args.files_name != NULL)
180
+ message_set_files(0);
181
+ else
182
+ message_set_files(args.arg_count);
183
+
184
+ // Refuse to write compressed data to standard output if it is
185
+ // a terminal.
186
+ if (opt_mode == MODE_COMPRESS) {
187
+ if (opt_stdout || (args.arg_count == 1
188
+ && strcmp(args.arg_names[0], "-") == 0)) {
189
+ if (is_tty_stdout()) {
190
+ message_try_help();
191
+ tuklib_exit(E_ERROR, E_ERROR, false);
192
+ }
193
+ }
194
+ }
195
+
196
+ // Set up the signal handlers. We don't need these before we
197
+ // start the actual action and not in --list mode, so this is
198
+ // done after parsing the command line arguments.
199
+ //
200
+ // It's good to keep signal handlers in normal compression and
201
+ // decompression modes even when only writing to stdout, because
202
+ // we might need to restore O_APPEND flag on stdout before exiting.
203
+ // In --test mode, signal handlers aren't really needed, but let's
204
+ // keep them there for consistency with normal decompression.
205
+ if (opt_mode != MODE_LIST)
206
+ signals_init();
207
+
208
+ #ifdef ENABLE_SANDBOX
209
+ // Set a flag that sandboxing is allowed if all these are true:
210
+ // - --files or --files0 wasn't used.
211
+ // - There is exactly one input file or we are reading from stdin.
212
+ // - We won't create any files: output goes to stdout or --test
213
+ // or --list was used. Note that --test implies opt_stdout = true
214
+ // but --list doesn't.
215
+ //
216
+ // This is obviously not ideal but it was easy to implement and
217
+ // it covers the most common use cases.
218
+ //
219
+ // TODO: Make sandboxing work for other situations too.
220
+ if (args.files_name == NULL && args.arg_count == 1
221
+ && (opt_stdout || strcmp("-", args.arg_names[0]) == 0
222
+ || opt_mode == MODE_LIST))
223
+ io_allow_sandbox();
224
+ #endif
225
+
226
+ // coder_run() handles compression, decompression, and testing.
227
+ // list_file() is for --list.
228
+ void (*run)(const char *filename) = &coder_run;
229
+ #ifdef HAVE_DECODERS
230
+ if (opt_mode == MODE_LIST)
231
+ run = &list_file;
232
+ #endif
233
+
234
+ // Process the files given on the command line. Note that if no names
235
+ // were given, args_parse() gave us a fake "-" filename.
236
+ for (unsigned i = 0; i < args.arg_count && !user_abort; ++i) {
237
+ if (strcmp("-", args.arg_names[i]) == 0) {
238
+ // Processing from stdin to stdout. Check that we
239
+ // aren't writing compressed data to a terminal or
240
+ // reading it from a terminal.
241
+ if (opt_mode == MODE_COMPRESS) {
242
+ if (is_tty_stdout())
243
+ continue;
244
+ } else if (is_tty_stdin()) {
245
+ continue;
246
+ }
247
+
248
+ // It doesn't make sense to compress data from stdin
249
+ // if we are supposed to read filenames from stdin
250
+ // too (enabled with --files or --files0).
251
+ if (args.files_name == stdin_filename) {
252
+ message_error(_("Cannot read data from "
253
+ "standard input when "
254
+ "reading filenames "
255
+ "from standard input"));
256
+ continue;
257
+ }
258
+
259
+ // Replace the "-" with a special pointer, which is
260
+ // recognized by coder_run() and other things.
261
+ // This way error messages get a proper filename
262
+ // string and the code still knows that it is
263
+ // handling the special case of stdin.
264
+ args.arg_names[i] = (char *)stdin_filename;
265
+ }
266
+
267
+ // Do the actual compression or decompression.
268
+ run(args.arg_names[i]);
269
+ }
270
+
271
+ // If --files or --files0 was used, process the filenames from the
272
+ // given file or stdin. Note that here we don't consider "-" to
273
+ // indicate stdin like we do with the command line arguments.
274
+ if (args.files_name != NULL) {
275
+ // read_name() checks for user_abort so we don't need to
276
+ // check it as loop termination condition.
277
+ while (true) {
278
+ const char *name = read_name(&args);
279
+ if (name == NULL)
280
+ break;
281
+
282
+ // read_name() doesn't return empty names.
283
+ assert(name[0] != '\0');
284
+ run(name);
285
+ }
286
+
287
+ if (args.files_name != stdin_filename)
288
+ (void)fclose(args.files_file);
289
+ }
290
+
291
+ #ifdef HAVE_DECODERS
292
+ // All files have now been handled. If in --list mode, display
293
+ // the totals before exiting. We don't have signal handlers
294
+ // enabled in --list mode, so we don't need to check user_abort.
295
+ if (opt_mode == MODE_LIST) {
296
+ assert(!user_abort);
297
+ list_totals();
298
+ }
299
+ #endif
300
+
301
+ #ifndef NDEBUG
302
+ coder_free();
303
+ args_free();
304
+ #endif
305
+
306
+ // If we have got a signal, raise it to kill the program instead
307
+ // of calling tuklib_exit().
308
+ signals_exit();
309
+
310
+ // Make a local copy of exit_status to keep the Windows code
311
+ // thread safe. At this point it is fine if we miss the user
312
+ // pressing C-c and don't set the exit_status to E_ERROR on
313
+ // Windows.
314
+ #if defined(_WIN32) && !defined(__CYGWIN__)
315
+ EnterCriticalSection(&exit_status_cs);
316
+ #endif
317
+
318
+ enum exit_status_type es = exit_status;
319
+
320
+ #if defined(_WIN32) && !defined(__CYGWIN__)
321
+ LeaveCriticalSection(&exit_status_cs);
322
+ #endif
323
+
324
+ // Suppress the exit status indicating a warning if --no-warn
325
+ // was specified.
326
+ if (es == E_WARNING && no_warn)
327
+ es = E_SUCCESS;
328
+
329
+ tuklib_exit(es, E_ERROR, message_verbosity_get() != V_SILENT);
330
+ }
@@ -0,0 +1,30 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file main.h
4
+ /// \brief Miscellaneous declarations
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
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ /// Possible exit status values. These are the same as used by gzip and bzip2.
14
+ enum exit_status_type {
15
+ E_SUCCESS = 0,
16
+ E_ERROR = 1,
17
+ E_WARNING = 2,
18
+ };
19
+
20
+
21
+ /// Sets the exit status after a warning or error has occurred. If new_status
22
+ /// is E_WARNING and the old exit status was already E_ERROR, the exit
23
+ /// status is not changed.
24
+ extern void set_exit_status(enum exit_status_type new_status);
25
+
26
+
27
+ /// Use E_SUCCESS instead of E_WARNING if something worth a warning occurs
28
+ /// but nothing worth an error has occurred. This is called when --no-warn
29
+ /// is specified.
30
+ extern void set_exit_no_warn(void);
@@ -0,0 +1,1258 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file message.c
4
+ /// \brief Printing messages
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
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ #include "private.h"
14
+
15
+ #include <stdarg.h>
16
+
17
+
18
+ /// Number of the current file
19
+ static unsigned int files_pos = 0;
20
+
21
+ /// Total number of input files; zero if unknown.
22
+ static unsigned int files_total;
23
+
24
+ /// Verbosity level
25
+ static enum message_verbosity verbosity = V_WARNING;
26
+
27
+ /// Filename which we will print with the verbose messages
28
+ static const char *filename;
29
+
30
+ /// True once the a filename has been printed to stderr as part of progress
31
+ /// message. If automatic progress updating isn't enabled, this becomes true
32
+ /// after the first progress message has been printed due to user sending
33
+ /// SIGINFO, SIGUSR1, or SIGALRM. Once this variable is true, we will print
34
+ /// an empty line before the next filename to make the output more readable.
35
+ static bool first_filename_printed = false;
36
+
37
+ /// This is set to true when we have printed the current filename to stderr
38
+ /// as part of a progress message. This variable is useful only if not
39
+ /// updating progress automatically: if user sends many SIGINFO, SIGUSR1, or
40
+ /// SIGALRM signals, we won't print the name of the same file multiple times.
41
+ static bool current_filename_printed = false;
42
+
43
+ /// True if we should print progress indicator and update it automatically
44
+ /// if also verbose >= V_VERBOSE.
45
+ static bool progress_automatic;
46
+
47
+ /// True if message_progress_start() has been called but
48
+ /// message_progress_end() hasn't been called yet.
49
+ static bool progress_started = false;
50
+
51
+ /// This is true when a progress message was printed and the cursor is still
52
+ /// on the same line with the progress message. In that case, a newline has
53
+ /// to be printed before any error messages.
54
+ static bool progress_active = false;
55
+
56
+ /// Pointer to lzma_stream used to do the encoding or decoding.
57
+ static lzma_stream *progress_strm;
58
+
59
+ /// Expected size of the input stream is needed to show completion percentage
60
+ /// and estimate remaining time.
61
+ static uint64_t expected_in_size;
62
+
63
+
64
+ // Use alarm() and SIGALRM when they are supported. This has two minor
65
+ // advantages over the alternative of polling gettimeofday():
66
+ // - It is possible for the user to send SIGINFO, SIGUSR1, or SIGALRM to
67
+ // get intermediate progress information even when --verbose wasn't used
68
+ // or stderr is not a terminal.
69
+ // - alarm() + SIGALRM seems to have slightly less overhead than polling
70
+ // gettimeofday().
71
+ #ifdef SIGALRM
72
+
73
+ const int message_progress_sigs[] = {
74
+ SIGALRM,
75
+ #ifdef SIGINFO
76
+ SIGINFO,
77
+ #endif
78
+ #ifdef SIGUSR1
79
+ SIGUSR1,
80
+ #endif
81
+ 0
82
+ };
83
+
84
+ /// The signal handler for SIGALRM sets this to true. It is set back to false
85
+ /// once the progress message has been updated.
86
+ static volatile sig_atomic_t progress_needs_updating = false;
87
+
88
+ /// Signal handler for SIGALRM
89
+ static void
90
+ progress_signal_handler(int sig lzma_attribute((__unused__)))
91
+ {
92
+ progress_needs_updating = true;
93
+ return;
94
+ }
95
+
96
+ #else
97
+
98
+ /// This is true when progress message printing is wanted. Using the same
99
+ /// variable name as above to avoid some ifdefs.
100
+ static bool progress_needs_updating = false;
101
+
102
+ /// Elapsed time when the next progress message update should be done.
103
+ static uint64_t progress_next_update;
104
+
105
+ #endif
106
+
107
+
108
+ extern void
109
+ message_init(void)
110
+ {
111
+ // If --verbose is used, we use a progress indicator if and only
112
+ // if stderr is a terminal. If stderr is not a terminal, we print
113
+ // verbose information only after finishing the file. As a special
114
+ // exception, even if --verbose was not used, user can send SIGALRM
115
+ // to make us print progress information once without automatic
116
+ // updating.
117
+ progress_automatic = isatty(STDERR_FILENO);
118
+
119
+ // Commented out because COLUMNS is rarely exported to environment.
120
+ // Most users have at least 80 columns anyway, let's think something
121
+ // fancy here if enough people complain.
122
+ /*
123
+ if (progress_automatic) {
124
+ // stderr is a terminal. Check the COLUMNS environment
125
+ // variable to see if the terminal is wide enough. If COLUMNS
126
+ // doesn't exist or it has some unparsable value, we assume
127
+ // that the terminal is wide enough.
128
+ const char *columns_str = getenv("COLUMNS");
129
+ if (columns_str != NULL) {
130
+ char *endptr;
131
+ const long columns = strtol(columns_str, &endptr, 10);
132
+ if (*endptr != '\0' || columns < 80)
133
+ progress_automatic = false;
134
+ }
135
+ }
136
+ */
137
+
138
+ #ifdef SIGALRM
139
+ // Establish the signal handlers which set a flag to tell us that
140
+ // progress info should be updated.
141
+ struct sigaction sa;
142
+ sigemptyset(&sa.sa_mask);
143
+ sa.sa_flags = 0;
144
+ sa.sa_handler = &progress_signal_handler;
145
+
146
+ for (size_t i = 0; message_progress_sigs[i] != 0; ++i)
147
+ if (sigaction(message_progress_sigs[i], &sa, NULL))
148
+ message_signal_handler();
149
+ #endif
150
+
151
+ return;
152
+ }
153
+
154
+
155
+ extern void
156
+ message_verbosity_increase(void)
157
+ {
158
+ if (verbosity < V_DEBUG)
159
+ ++verbosity;
160
+
161
+ return;
162
+ }
163
+
164
+
165
+ extern void
166
+ message_verbosity_decrease(void)
167
+ {
168
+ if (verbosity > V_SILENT)
169
+ --verbosity;
170
+
171
+ return;
172
+ }
173
+
174
+
175
+ extern enum message_verbosity
176
+ message_verbosity_get(void)
177
+ {
178
+ return verbosity;
179
+ }
180
+
181
+
182
+ extern void
183
+ message_set_files(unsigned int files)
184
+ {
185
+ files_total = files;
186
+ return;
187
+ }
188
+
189
+
190
+ /// Prints the name of the current file if it hasn't been printed already,
191
+ /// except if we are processing exactly one stream from stdin to stdout.
192
+ /// I think it looks nicer to not print "(stdin)" when --verbose is used
193
+ /// in a pipe and no other files are processed.
194
+ static void
195
+ print_filename(void)
196
+ {
197
+ if (!opt_robot && (files_total != 1 || filename != stdin_filename)) {
198
+ signals_block();
199
+
200
+ FILE *file = opt_mode == MODE_LIST ? stdout : stderr;
201
+
202
+ // If a file was already processed, put an empty line
203
+ // before the next filename to improve readability.
204
+ if (first_filename_printed)
205
+ fputc('\n', file);
206
+
207
+ first_filename_printed = true;
208
+ current_filename_printed = true;
209
+
210
+ // If we don't know how many files there will be due
211
+ // to usage of --files or --files0.
212
+ if (files_total == 0)
213
+ fprintf(file, "%s (%u)\n", filename,
214
+ files_pos);
215
+ else
216
+ fprintf(file, "%s (%u/%u)\n", filename,
217
+ files_pos, files_total);
218
+
219
+ signals_unblock();
220
+ }
221
+
222
+ return;
223
+ }
224
+
225
+
226
+ extern void
227
+ message_filename(const char *src_name)
228
+ {
229
+ // Start numbering the files starting from one.
230
+ ++files_pos;
231
+ filename = src_name;
232
+
233
+ if (verbosity >= V_VERBOSE
234
+ && (progress_automatic || opt_mode == MODE_LIST))
235
+ print_filename();
236
+ else
237
+ current_filename_printed = false;
238
+
239
+ return;
240
+ }
241
+
242
+
243
+ extern void
244
+ message_progress_start(lzma_stream *strm, uint64_t in_size)
245
+ {
246
+ // Store the pointer to the lzma_stream used to do the coding.
247
+ // It is needed to find out the position in the stream.
248
+ progress_strm = strm;
249
+
250
+ // Store the expected size of the file. If we aren't printing any
251
+ // statistics, then is will be unused. But since it is possible
252
+ // that the user sends us a signal to show statistics, we need
253
+ // to have it available anyway.
254
+ expected_in_size = in_size;
255
+
256
+ // Indicate that progress info may need to be printed before
257
+ // printing error messages.
258
+ progress_started = true;
259
+
260
+ // If progress indicator is wanted, print the filename and possibly
261
+ // the file count now.
262
+ if (verbosity >= V_VERBOSE && progress_automatic) {
263
+ // Start the timer to display the first progress message
264
+ // after one second. An alternative would be to show the
265
+ // first message almost immediately, but delaying by one
266
+ // second looks better to me, since extremely early
267
+ // progress info is pretty much useless.
268
+ #ifdef SIGALRM
269
+ // First disable a possibly existing alarm.
270
+ alarm(0);
271
+ progress_needs_updating = false;
272
+ alarm(1);
273
+ #else
274
+ progress_needs_updating = true;
275
+ progress_next_update = 1000;
276
+ #endif
277
+ }
278
+
279
+ return;
280
+ }
281
+
282
+
283
+ /// Make the string indicating completion percentage.
284
+ static const char *
285
+ progress_percentage(uint64_t in_pos)
286
+ {
287
+ // If the size of the input file is unknown or the size told us is
288
+ // clearly wrong since we have processed more data than the alleged
289
+ // size of the file, show a static string indicating that we have
290
+ // no idea of the completion percentage.
291
+ if (expected_in_size == 0 || in_pos > expected_in_size)
292
+ return "--- %";
293
+
294
+ // Never show 100.0 % before we actually are finished.
295
+ double percentage = (double)(in_pos) / (double)(expected_in_size)
296
+ * 99.9;
297
+
298
+ // Use big enough buffer to hold e.g. a multibyte decimal point.
299
+ static char buf[16];
300
+ snprintf(buf, sizeof(buf), "%.1f %%", percentage);
301
+
302
+ return buf;
303
+ }
304
+
305
+
306
+ /// Make the string containing the amount of input processed, amount of
307
+ /// output produced, and the compression ratio.
308
+ static const char *
309
+ progress_sizes(uint64_t compressed_pos, uint64_t uncompressed_pos, bool final)
310
+ {
311
+ // Use big enough buffer to hold e.g. a multibyte thousand separators.
312
+ static char buf[128];
313
+ char *pos = buf;
314
+ size_t left = sizeof(buf);
315
+
316
+ // Print the sizes. If this the final message, use more reasonable
317
+ // units than MiB if the file was small.
318
+ const enum nicestr_unit unit_min = final ? NICESTR_B : NICESTR_MIB;
319
+ my_snprintf(&pos, &left, "%s / %s",
320
+ uint64_to_nicestr(compressed_pos,
321
+ unit_min, NICESTR_TIB, false, 0),
322
+ uint64_to_nicestr(uncompressed_pos,
323
+ unit_min, NICESTR_TIB, false, 1));
324
+
325
+ // Avoid division by zero. If we cannot calculate the ratio, set
326
+ // it to some nice number greater than 10.0 so that it gets caught
327
+ // in the next if-clause.
328
+ const double ratio = uncompressed_pos > 0
329
+ ? (double)(compressed_pos) / (double)(uncompressed_pos)
330
+ : 16.0;
331
+
332
+ // If the ratio is very bad, just indicate that it is greater than
333
+ // 9.999. This way the length of the ratio field stays fixed.
334
+ if (ratio > 9.999)
335
+ snprintf(pos, left, " > %.3f", 9.999);
336
+ else
337
+ snprintf(pos, left, " = %.3f", ratio);
338
+
339
+ return buf;
340
+ }
341
+
342
+
343
+ /// Make the string containing the processing speed of uncompressed data.
344
+ static const char *
345
+ progress_speed(uint64_t uncompressed_pos, uint64_t elapsed)
346
+ {
347
+ // Don't print the speed immediately, since the early values look
348
+ // somewhat random.
349
+ if (elapsed < 3000)
350
+ return "";
351
+
352
+ static const char unit[][8] = {
353
+ "KiB/s",
354
+ "MiB/s",
355
+ "GiB/s",
356
+ };
357
+
358
+ size_t unit_index = 0;
359
+
360
+ // Calculate the speed as KiB/s.
361
+ double speed = (double)(uncompressed_pos)
362
+ / ((double)(elapsed) * (1024.0 / 1000.0));
363
+
364
+ // Adjust the unit of the speed if needed.
365
+ while (speed > 999.0) {
366
+ speed /= 1024.0;
367
+ if (++unit_index == ARRAY_SIZE(unit))
368
+ return ""; // Way too fast ;-)
369
+ }
370
+
371
+ // Use decimal point only if the number is small. Examples:
372
+ // - 0.1 KiB/s
373
+ // - 9.9 KiB/s
374
+ // - 99 KiB/s
375
+ // - 999 KiB/s
376
+ // Use big enough buffer to hold e.g. a multibyte decimal point.
377
+ static char buf[16];
378
+ snprintf(buf, sizeof(buf), "%.*f %s",
379
+ speed > 9.9 ? 0 : 1, speed, unit[unit_index]);
380
+ return buf;
381
+ }
382
+
383
+
384
+ /// Make a string indicating elapsed time. The format is either
385
+ /// M:SS or H:MM:SS depending on if the time is an hour or more.
386
+ static const char *
387
+ progress_time(uint64_t mseconds)
388
+ {
389
+ // 9999 hours = 416 days
390
+ static char buf[sizeof("9999:59:59")];
391
+
392
+ // 32-bit variable is enough for elapsed time (136 years).
393
+ uint32_t seconds = (uint32_t)(mseconds / 1000);
394
+
395
+ // Don't show anything if the time is zero or ridiculously big.
396
+ if (seconds == 0 || seconds > ((9999 * 60) + 59) * 60 + 59)
397
+ return "";
398
+
399
+ uint32_t minutes = seconds / 60;
400
+ seconds %= 60;
401
+
402
+ if (minutes >= 60) {
403
+ const uint32_t hours = minutes / 60;
404
+ minutes %= 60;
405
+ snprintf(buf, sizeof(buf),
406
+ "%" PRIu32 ":%02" PRIu32 ":%02" PRIu32,
407
+ hours, minutes, seconds);
408
+ } else {
409
+ snprintf(buf, sizeof(buf), "%" PRIu32 ":%02" PRIu32,
410
+ minutes, seconds);
411
+ }
412
+
413
+ return buf;
414
+ }
415
+
416
+
417
+ /// Return a string containing estimated remaining time when
418
+ /// reasonably possible.
419
+ static const char *
420
+ progress_remaining(uint64_t in_pos, uint64_t elapsed)
421
+ {
422
+ // Don't show the estimated remaining time when it wouldn't
423
+ // make sense:
424
+ // - Input size is unknown.
425
+ // - Input has grown bigger since we started (de)compressing.
426
+ // - We haven't processed much data yet, so estimate would be
427
+ // too inaccurate.
428
+ // - Only a few seconds has passed since we started (de)compressing,
429
+ // so estimate would be too inaccurate.
430
+ if (expected_in_size == 0 || in_pos > expected_in_size
431
+ || in_pos < (UINT64_C(1) << 19) || elapsed < 8000)
432
+ return "";
433
+
434
+ // Calculate the estimate. Don't give an estimate of zero seconds,
435
+ // since it is possible that all the input has been already passed
436
+ // to the library, but there is still quite a bit of output pending.
437
+ uint32_t remaining = (double)(expected_in_size - in_pos)
438
+ * ((double)(elapsed) / 1000.0) / (double)(in_pos);
439
+ if (remaining < 1)
440
+ remaining = 1;
441
+
442
+ static char buf[sizeof("9 h 55 min")];
443
+
444
+ // Select appropriate precision for the estimated remaining time.
445
+ if (remaining <= 10) {
446
+ // A maximum of 10 seconds remaining.
447
+ // Show the number of seconds as is.
448
+ snprintf(buf, sizeof(buf), "%" PRIu32 " s", remaining);
449
+
450
+ } else if (remaining <= 50) {
451
+ // A maximum of 50 seconds remaining.
452
+ // Round up to the next multiple of five seconds.
453
+ remaining = (remaining + 4) / 5 * 5;
454
+ snprintf(buf, sizeof(buf), "%" PRIu32 " s", remaining);
455
+
456
+ } else if (remaining <= 590) {
457
+ // A maximum of 9 minutes and 50 seconds remaining.
458
+ // Round up to the next multiple of ten seconds.
459
+ remaining = (remaining + 9) / 10 * 10;
460
+ snprintf(buf, sizeof(buf), "%" PRIu32 " min %" PRIu32 " s",
461
+ remaining / 60, remaining % 60);
462
+
463
+ } else if (remaining <= 59 * 60) {
464
+ // A maximum of 59 minutes remaining.
465
+ // Round up to the next multiple of a minute.
466
+ remaining = (remaining + 59) / 60;
467
+ snprintf(buf, sizeof(buf), "%" PRIu32 " min", remaining);
468
+
469
+ } else if (remaining <= 9 * 3600 + 50 * 60) {
470
+ // A maximum of 9 hours and 50 minutes left.
471
+ // Round up to the next multiple of ten minutes.
472
+ remaining = (remaining + 599) / 600 * 10;
473
+ snprintf(buf, sizeof(buf), "%" PRIu32 " h %" PRIu32 " min",
474
+ remaining / 60, remaining % 60);
475
+
476
+ } else if (remaining <= 23 * 3600) {
477
+ // A maximum of 23 hours remaining.
478
+ // Round up to the next multiple of an hour.
479
+ remaining = (remaining + 3599) / 3600;
480
+ snprintf(buf, sizeof(buf), "%" PRIu32 " h", remaining);
481
+
482
+ } else if (remaining <= 9 * 24 * 3600 + 23 * 3600) {
483
+ // A maximum of 9 days and 23 hours remaining.
484
+ // Round up to the next multiple of an hour.
485
+ remaining = (remaining + 3599) / 3600;
486
+ snprintf(buf, sizeof(buf), "%" PRIu32 " d %" PRIu32 " h",
487
+ remaining / 24, remaining % 24);
488
+
489
+ } else if (remaining <= 999 * 24 * 3600) {
490
+ // A maximum of 999 days remaining. ;-)
491
+ // Round up to the next multiple of a day.
492
+ remaining = (remaining + 24 * 3600 - 1) / (24 * 3600);
493
+ snprintf(buf, sizeof(buf), "%" PRIu32 " d", remaining);
494
+
495
+ } else {
496
+ // The estimated remaining time is too big. Don't show it.
497
+ return "";
498
+ }
499
+
500
+ return buf;
501
+ }
502
+
503
+
504
+ /// Get how much uncompressed and compressed data has been processed.
505
+ static void
506
+ progress_pos(uint64_t *in_pos,
507
+ uint64_t *compressed_pos, uint64_t *uncompressed_pos)
508
+ {
509
+ uint64_t out_pos;
510
+ lzma_get_progress(progress_strm, in_pos, &out_pos);
511
+
512
+ // It cannot have processed more input than it has been given.
513
+ assert(*in_pos <= progress_strm->total_in);
514
+
515
+ // It cannot have produced more output than it claims to have ready.
516
+ assert(out_pos >= progress_strm->total_out);
517
+
518
+ if (opt_mode == MODE_COMPRESS) {
519
+ *compressed_pos = out_pos;
520
+ *uncompressed_pos = *in_pos;
521
+ } else {
522
+ *compressed_pos = *in_pos;
523
+ *uncompressed_pos = out_pos;
524
+ }
525
+
526
+ return;
527
+ }
528
+
529
+
530
+ extern void
531
+ message_progress_update(void)
532
+ {
533
+ if (!progress_needs_updating)
534
+ return;
535
+
536
+ // Calculate how long we have been processing this file.
537
+ const uint64_t elapsed = mytime_get_elapsed();
538
+
539
+ #ifndef SIGALRM
540
+ if (progress_next_update > elapsed)
541
+ return;
542
+
543
+ progress_next_update = elapsed + 1000;
544
+ #endif
545
+
546
+ // Get our current position in the stream.
547
+ uint64_t in_pos;
548
+ uint64_t compressed_pos;
549
+ uint64_t uncompressed_pos;
550
+ progress_pos(&in_pos, &compressed_pos, &uncompressed_pos);
551
+
552
+ // Block signals so that fprintf() doesn't get interrupted.
553
+ signals_block();
554
+
555
+ // Print the filename if it hasn't been printed yet.
556
+ if (!current_filename_printed)
557
+ print_filename();
558
+
559
+ // Print the actual progress message. The idea is that there is at
560
+ // least three spaces between the fields in typical situations, but
561
+ // even in rare situations there is at least one space.
562
+ const char *cols[5] = {
563
+ progress_percentage(in_pos),
564
+ progress_sizes(compressed_pos, uncompressed_pos, false),
565
+ progress_speed(uncompressed_pos, elapsed),
566
+ progress_time(elapsed),
567
+ progress_remaining(in_pos, elapsed),
568
+ };
569
+ fprintf(stderr, "\r %*s %*s %*s %10s %10s\r",
570
+ tuklib_mbstr_fw(cols[0], 6), cols[0],
571
+ tuklib_mbstr_fw(cols[1], 35), cols[1],
572
+ tuklib_mbstr_fw(cols[2], 9), cols[2],
573
+ cols[3],
574
+ cols[4]);
575
+
576
+ #ifdef SIGALRM
577
+ // Updating the progress info was finished. Reset
578
+ // progress_needs_updating to wait for the next SIGALRM.
579
+ //
580
+ // NOTE: This has to be done before alarm(1) or with (very) bad
581
+ // luck we could be setting this to false after the alarm has already
582
+ // been triggered.
583
+ progress_needs_updating = false;
584
+
585
+ if (verbosity >= V_VERBOSE && progress_automatic) {
586
+ // Mark that the progress indicator is active, so if an error
587
+ // occurs, the error message gets printed cleanly.
588
+ progress_active = true;
589
+
590
+ // Restart the timer so that progress_needs_updating gets
591
+ // set to true after about one second.
592
+ alarm(1);
593
+ } else {
594
+ // The progress message was printed because user had sent us
595
+ // SIGALRM. In this case, each progress message is printed
596
+ // on its own line.
597
+ fputc('\n', stderr);
598
+ }
599
+ #else
600
+ // When SIGALRM isn't supported and we get here, it's always due to
601
+ // automatic progress update. We set progress_active here too like
602
+ // described above.
603
+ assert(verbosity >= V_VERBOSE);
604
+ assert(progress_automatic);
605
+ progress_active = true;
606
+ #endif
607
+
608
+ signals_unblock();
609
+
610
+ return;
611
+ }
612
+
613
+
614
+ static void
615
+ progress_flush(bool finished)
616
+ {
617
+ if (!progress_started || verbosity < V_VERBOSE)
618
+ return;
619
+
620
+ uint64_t in_pos;
621
+ uint64_t compressed_pos;
622
+ uint64_t uncompressed_pos;
623
+ progress_pos(&in_pos, &compressed_pos, &uncompressed_pos);
624
+
625
+ // Avoid printing intermediate progress info if some error occurs
626
+ // in the beginning of the stream. (If something goes wrong later in
627
+ // the stream, it is sometimes useful to tell the user where the
628
+ // error approximately occurred, especially if the error occurs
629
+ // after a time-consuming operation.)
630
+ if (!finished && !progress_active
631
+ && (compressed_pos == 0 || uncompressed_pos == 0))
632
+ return;
633
+
634
+ progress_active = false;
635
+
636
+ const uint64_t elapsed = mytime_get_elapsed();
637
+
638
+ signals_block();
639
+
640
+ // When using the auto-updating progress indicator, the final
641
+ // statistics are printed in the same format as the progress
642
+ // indicator itself.
643
+ if (progress_automatic) {
644
+ const char *cols[5] = {
645
+ finished ? "100 %" : progress_percentage(in_pos),
646
+ progress_sizes(compressed_pos, uncompressed_pos, true),
647
+ progress_speed(uncompressed_pos, elapsed),
648
+ progress_time(elapsed),
649
+ finished ? "" : progress_remaining(in_pos, elapsed),
650
+ };
651
+ fprintf(stderr, "\r %*s %*s %*s %10s %10s\n",
652
+ tuklib_mbstr_fw(cols[0], 6), cols[0],
653
+ tuklib_mbstr_fw(cols[1], 35), cols[1],
654
+ tuklib_mbstr_fw(cols[2], 9), cols[2],
655
+ cols[3],
656
+ cols[4]);
657
+ } else {
658
+ // The filename is always printed.
659
+ fprintf(stderr, "%s: ", filename);
660
+
661
+ // Percentage is printed only if we didn't finish yet.
662
+ if (!finished) {
663
+ // Don't print the percentage when it isn't known
664
+ // (starts with a dash).
665
+ const char *percentage = progress_percentage(in_pos);
666
+ if (percentage[0] != '-')
667
+ fprintf(stderr, "%s, ", percentage);
668
+ }
669
+
670
+ // Size information is always printed.
671
+ fprintf(stderr, "%s", progress_sizes(
672
+ compressed_pos, uncompressed_pos, true));
673
+
674
+ // The speed and elapsed time aren't always shown.
675
+ const char *speed = progress_speed(uncompressed_pos, elapsed);
676
+ if (speed[0] != '\0')
677
+ fprintf(stderr, ", %s", speed);
678
+
679
+ const char *elapsed_str = progress_time(elapsed);
680
+ if (elapsed_str[0] != '\0')
681
+ fprintf(stderr, ", %s", elapsed_str);
682
+
683
+ fputc('\n', stderr);
684
+ }
685
+
686
+ signals_unblock();
687
+
688
+ return;
689
+ }
690
+
691
+
692
+ extern void
693
+ message_progress_end(bool success)
694
+ {
695
+ assert(progress_started);
696
+ progress_flush(success);
697
+ progress_started = false;
698
+ return;
699
+ }
700
+
701
+
702
+ static void
703
+ vmessage(enum message_verbosity v, const char *fmt, va_list ap)
704
+ {
705
+ if (v <= verbosity) {
706
+ signals_block();
707
+
708
+ progress_flush(false);
709
+
710
+ // TRANSLATORS: This is the program name in the beginning
711
+ // of the line in messages. Usually it becomes "xz: ".
712
+ // This is a translatable string because French needs
713
+ // a space before a colon.
714
+ fprintf(stderr, _("%s: "), progname);
715
+ vfprintf(stderr, fmt, ap);
716
+ fputc('\n', stderr);
717
+
718
+ signals_unblock();
719
+ }
720
+
721
+ return;
722
+ }
723
+
724
+
725
+ extern void
726
+ message(enum message_verbosity v, const char *fmt, ...)
727
+ {
728
+ va_list ap;
729
+ va_start(ap, fmt);
730
+ vmessage(v, fmt, ap);
731
+ va_end(ap);
732
+ return;
733
+ }
734
+
735
+
736
+ extern void
737
+ message_warning(const char *fmt, ...)
738
+ {
739
+ va_list ap;
740
+ va_start(ap, fmt);
741
+ vmessage(V_WARNING, fmt, ap);
742
+ va_end(ap);
743
+
744
+ set_exit_status(E_WARNING);
745
+ return;
746
+ }
747
+
748
+
749
+ extern void
750
+ message_error(const char *fmt, ...)
751
+ {
752
+ va_list ap;
753
+ va_start(ap, fmt);
754
+ vmessage(V_ERROR, fmt, ap);
755
+ va_end(ap);
756
+
757
+ set_exit_status(E_ERROR);
758
+ return;
759
+ }
760
+
761
+
762
+ extern void
763
+ message_fatal(const char *fmt, ...)
764
+ {
765
+ va_list ap;
766
+ va_start(ap, fmt);
767
+ vmessage(V_ERROR, fmt, ap);
768
+ va_end(ap);
769
+
770
+ tuklib_exit(E_ERROR, E_ERROR, false);
771
+ }
772
+
773
+
774
+ extern void
775
+ message_bug(void)
776
+ {
777
+ message_fatal(_("Internal error (bug)"));
778
+ }
779
+
780
+
781
+ extern void
782
+ message_signal_handler(void)
783
+ {
784
+ message_fatal(_("Cannot establish signal handlers"));
785
+ }
786
+
787
+
788
+ extern const char *
789
+ message_strm(lzma_ret code)
790
+ {
791
+ switch (code) {
792
+ case LZMA_NO_CHECK:
793
+ return _("No integrity check; not verifying file integrity");
794
+
795
+ case LZMA_UNSUPPORTED_CHECK:
796
+ return _("Unsupported type of integrity check; "
797
+ "not verifying file integrity");
798
+
799
+ case LZMA_MEM_ERROR:
800
+ return strerror(ENOMEM);
801
+
802
+ case LZMA_MEMLIMIT_ERROR:
803
+ return _("Memory usage limit reached");
804
+
805
+ case LZMA_FORMAT_ERROR:
806
+ return _("File format not recognized");
807
+
808
+ case LZMA_OPTIONS_ERROR:
809
+ return _("Unsupported options");
810
+
811
+ case LZMA_DATA_ERROR:
812
+ return _("Compressed data is corrupt");
813
+
814
+ case LZMA_BUF_ERROR:
815
+ return _("Unexpected end of input");
816
+
817
+ case LZMA_OK:
818
+ case LZMA_STREAM_END:
819
+ case LZMA_GET_CHECK:
820
+ case LZMA_PROG_ERROR:
821
+ // Without "default", compiler will warn if new constants
822
+ // are added to lzma_ret, it is not too easy to forget to
823
+ // add the new constants to this function.
824
+ break;
825
+ }
826
+
827
+ return _("Internal error (bug)");
828
+ }
829
+
830
+
831
+ extern void
832
+ message_mem_needed(enum message_verbosity v, uint64_t memusage)
833
+ {
834
+ if (v > verbosity)
835
+ return;
836
+
837
+ // Convert memusage to MiB, rounding up to the next full MiB.
838
+ // This way the user can always use the displayed usage as
839
+ // the new memory usage limit. (If we rounded to the nearest,
840
+ // the user might need to +1 MiB to get high enough limit.)
841
+ memusage = round_up_to_mib(memusage);
842
+
843
+ uint64_t memlimit = hardware_memlimit_get(opt_mode);
844
+
845
+ // Handle the case when there is no memory usage limit.
846
+ // This way we don't print a weird message with a huge number.
847
+ if (memlimit == UINT64_MAX) {
848
+ message(v, _("%s MiB of memory is required. "
849
+ "The limiter is disabled."),
850
+ uint64_to_str(memusage, 0));
851
+ return;
852
+ }
853
+
854
+ // With US-ASCII:
855
+ // 2^64 with thousand separators + " MiB" suffix + '\0' = 26 + 4 + 1
856
+ // But there may be multibyte chars so reserve enough space.
857
+ char memlimitstr[128];
858
+
859
+ // Show the memory usage limit as MiB unless it is less than 1 MiB.
860
+ // This way it's easy to notice errors where one has typed
861
+ // --memory=123 instead of --memory=123MiB.
862
+ if (memlimit < (UINT32_C(1) << 20)) {
863
+ snprintf(memlimitstr, sizeof(memlimitstr), "%s B",
864
+ uint64_to_str(memlimit, 1));
865
+ } else {
866
+ // Round up just like with memusage. If this function is
867
+ // called for informational purposes (to just show the
868
+ // current usage and limit), we should never show that
869
+ // the usage is higher than the limit, which would give
870
+ // a false impression that the memory usage limit isn't
871
+ // properly enforced.
872
+ snprintf(memlimitstr, sizeof(memlimitstr), "%s MiB",
873
+ uint64_to_str(round_up_to_mib(memlimit), 1));
874
+ }
875
+
876
+ message(v, _("%s MiB of memory is required. The limit is %s."),
877
+ uint64_to_str(memusage, 0), memlimitstr);
878
+
879
+ return;
880
+ }
881
+
882
+
883
+ /// \brief Convert uint32_t to a nice string for --lzma[12]=dict=SIZE
884
+ ///
885
+ /// The idea is to use KiB or MiB suffix when possible.
886
+ static const char *
887
+ uint32_to_optstr(uint32_t num)
888
+ {
889
+ static char buf[16];
890
+
891
+ if ((num & ((UINT32_C(1) << 20) - 1)) == 0)
892
+ snprintf(buf, sizeof(buf), "%" PRIu32 "MiB", num >> 20);
893
+ else if ((num & ((UINT32_C(1) << 10) - 1)) == 0)
894
+ snprintf(buf, sizeof(buf), "%" PRIu32 "KiB", num >> 10);
895
+ else
896
+ snprintf(buf, sizeof(buf), "%" PRIu32, num);
897
+
898
+ return buf;
899
+ }
900
+
901
+
902
+ extern void
903
+ message_filters_to_str(char buf[FILTERS_STR_SIZE],
904
+ const lzma_filter *filters, bool all_known)
905
+ {
906
+ char *pos = buf;
907
+ size_t left = FILTERS_STR_SIZE;
908
+
909
+ for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
910
+ // Add the dashes for the filter option. A space is
911
+ // needed after the first and later filters.
912
+ my_snprintf(&pos, &left, "%s", i == 0 ? "--" : " --");
913
+
914
+ switch (filters[i].id) {
915
+ case LZMA_FILTER_LZMA1:
916
+ case LZMA_FILTER_LZMA2: {
917
+ const lzma_options_lzma *opt = filters[i].options;
918
+ const char *mode = NULL;
919
+ const char *mf = NULL;
920
+
921
+ if (all_known) {
922
+ switch (opt->mode) {
923
+ case LZMA_MODE_FAST:
924
+ mode = "fast";
925
+ break;
926
+
927
+ case LZMA_MODE_NORMAL:
928
+ mode = "normal";
929
+ break;
930
+
931
+ default:
932
+ mode = "UNKNOWN";
933
+ break;
934
+ }
935
+
936
+ switch (opt->mf) {
937
+ case LZMA_MF_HC3:
938
+ mf = "hc3";
939
+ break;
940
+
941
+ case LZMA_MF_HC4:
942
+ mf = "hc4";
943
+ break;
944
+
945
+ case LZMA_MF_BT2:
946
+ mf = "bt2";
947
+ break;
948
+
949
+ case LZMA_MF_BT3:
950
+ mf = "bt3";
951
+ break;
952
+
953
+ case LZMA_MF_BT4:
954
+ mf = "bt4";
955
+ break;
956
+
957
+ default:
958
+ mf = "UNKNOWN";
959
+ break;
960
+ }
961
+ }
962
+
963
+ // Add the filter name and dictionary size, which
964
+ // is always known.
965
+ my_snprintf(&pos, &left, "lzma%c=dict=%s",
966
+ filters[i].id == LZMA_FILTER_LZMA2
967
+ ? '2' : '1',
968
+ uint32_to_optstr(opt->dict_size));
969
+
970
+ // With LZMA1 also lc/lp/pb are known when
971
+ // decompressing, but this function is never
972
+ // used to print information about .lzma headers.
973
+ assert(filters[i].id == LZMA_FILTER_LZMA2
974
+ || all_known);
975
+
976
+ // Print the rest of the options, which are known
977
+ // only when compressing.
978
+ if (all_known)
979
+ my_snprintf(&pos, &left,
980
+ ",lc=%" PRIu32 ",lp=%" PRIu32
981
+ ",pb=%" PRIu32
982
+ ",mode=%s,nice=%" PRIu32 ",mf=%s"
983
+ ",depth=%" PRIu32,
984
+ opt->lc, opt->lp, opt->pb,
985
+ mode, opt->nice_len, mf, opt->depth);
986
+ break;
987
+ }
988
+
989
+ case LZMA_FILTER_X86:
990
+ case LZMA_FILTER_POWERPC:
991
+ case LZMA_FILTER_IA64:
992
+ case LZMA_FILTER_ARM:
993
+ case LZMA_FILTER_ARMTHUMB:
994
+ case LZMA_FILTER_SPARC: {
995
+ static const char bcj_names[][9] = {
996
+ "x86",
997
+ "powerpc",
998
+ "ia64",
999
+ "arm",
1000
+ "armthumb",
1001
+ "sparc",
1002
+ };
1003
+
1004
+ const lzma_options_bcj *opt = filters[i].options;
1005
+ my_snprintf(&pos, &left, "%s", bcj_names[filters[i].id
1006
+ - LZMA_FILTER_X86]);
1007
+
1008
+ // Show the start offset only when really needed.
1009
+ if (opt != NULL && opt->start_offset != 0)
1010
+ my_snprintf(&pos, &left, "=start=%" PRIu32,
1011
+ opt->start_offset);
1012
+
1013
+ break;
1014
+ }
1015
+
1016
+ case LZMA_FILTER_DELTA: {
1017
+ const lzma_options_delta *opt = filters[i].options;
1018
+ my_snprintf(&pos, &left, "delta=dist=%" PRIu32,
1019
+ opt->dist);
1020
+ break;
1021
+ }
1022
+
1023
+ default:
1024
+ // This should be possible only if liblzma is
1025
+ // newer than the xz tool.
1026
+ my_snprintf(&pos, &left, "UNKNOWN");
1027
+ break;
1028
+ }
1029
+ }
1030
+
1031
+ return;
1032
+ }
1033
+
1034
+
1035
+ extern void
1036
+ message_filters_show(enum message_verbosity v, const lzma_filter *filters)
1037
+ {
1038
+ if (v > verbosity)
1039
+ return;
1040
+
1041
+ char buf[FILTERS_STR_SIZE];
1042
+ message_filters_to_str(buf, filters, true);
1043
+ fprintf(stderr, _("%s: Filter chain: %s\n"), progname, buf);
1044
+ return;
1045
+ }
1046
+
1047
+
1048
+ extern void
1049
+ message_try_help(void)
1050
+ {
1051
+ // Print this with V_WARNING instead of V_ERROR to prevent it from
1052
+ // showing up when --quiet has been specified.
1053
+ message(V_WARNING, _("Try `%s --help' for more information."),
1054
+ progname);
1055
+ return;
1056
+ }
1057
+
1058
+
1059
+ extern void
1060
+ message_version(void)
1061
+ {
1062
+ // It is possible that liblzma version is different than the command
1063
+ // line tool version, so print both.
1064
+ if (opt_robot) {
1065
+ printf("XZ_VERSION=%" PRIu32 "\nLIBLZMA_VERSION=%" PRIu32 "\n",
1066
+ LZMA_VERSION, lzma_version_number());
1067
+ } else {
1068
+ printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
1069
+ printf("liblzma %s\n", lzma_version_string());
1070
+ }
1071
+
1072
+ tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
1073
+ }
1074
+
1075
+
1076
+ extern void
1077
+ message_help(bool long_help)
1078
+ {
1079
+ printf(_("Usage: %s [OPTION]... [FILE]...\n"
1080
+ "Compress or decompress FILEs in the .xz format.\n\n"),
1081
+ progname);
1082
+
1083
+ // NOTE: The short help doesn't currently have options that
1084
+ // take arguments.
1085
+ if (long_help)
1086
+ puts(_("Mandatory arguments to long options are mandatory "
1087
+ "for short options too.\n"));
1088
+
1089
+ if (long_help)
1090
+ puts(_(" Operation mode:\n"));
1091
+
1092
+ puts(_(
1093
+ " -z, --compress force compression\n"
1094
+ " -d, --decompress force decompression\n"
1095
+ " -t, --test test compressed file integrity\n"
1096
+ " -l, --list list information about .xz files"));
1097
+
1098
+ if (long_help)
1099
+ puts(_("\n Operation modifiers:\n"));
1100
+
1101
+ puts(_(
1102
+ " -k, --keep keep (don't delete) input files\n"
1103
+ " -f, --force force overwrite of output file and (de)compress links\n"
1104
+ " -c, --stdout write to standard output and don't delete input files"));
1105
+
1106
+ if (long_help) {
1107
+ puts(_(
1108
+ " --single-stream decompress only the first stream, and silently\n"
1109
+ " ignore possible remaining input data"));
1110
+ puts(_(
1111
+ " --no-sparse do not create sparse files when decompressing\n"
1112
+ " -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
1113
+ " --files[=FILE] read filenames to process from FILE; if FILE is\n"
1114
+ " omitted, filenames are read from the standard input;\n"
1115
+ " filenames must be terminated with the newline character\n"
1116
+ " --files0[=FILE] like --files but use the null character as terminator"));
1117
+ }
1118
+
1119
+ if (long_help) {
1120
+ puts(_("\n Basic file format and compression options:\n"));
1121
+ puts(_(
1122
+ " -F, --format=FMT file format to encode or decode; possible values are\n"
1123
+ " `auto' (default), `xz', `lzma', and `raw'\n"
1124
+ " -C, --check=CHECK integrity check type: `none' (use with caution),\n"
1125
+ " `crc32', `crc64' (default), or `sha256'"));
1126
+ puts(_(
1127
+ " --ignore-check don't verify the integrity check when decompressing"));
1128
+ }
1129
+
1130
+ puts(_(
1131
+ " -0 ... -9 compression preset; default is 6; take compressor *and*\n"
1132
+ " decompressor memory usage into account before using 7-9!"));
1133
+
1134
+ puts(_(
1135
+ " -e, --extreme try to improve compression ratio by using more CPU time;\n"
1136
+ " does not affect decompressor memory requirements"));
1137
+
1138
+ puts(_(
1139
+ " -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
1140
+ " to use as many threads as there are processor cores"));
1141
+
1142
+ if (long_help) {
1143
+ puts(_(
1144
+ " --block-size=SIZE\n"
1145
+ " start a new .xz block after every SIZE bytes of input;\n"
1146
+ " use this to set the block size for threaded compression"));
1147
+ puts(_(
1148
+ " --block-list=SIZES\n"
1149
+ " start a new .xz block after the given comma-separated\n"
1150
+ " intervals of uncompressed data"));
1151
+ puts(_(
1152
+ " --flush-timeout=TIMEOUT\n"
1153
+ " when compressing, if more than TIMEOUT milliseconds has\n"
1154
+ " passed since the previous flush and reading more input\n"
1155
+ " would block, all pending data is flushed out"
1156
+ ));
1157
+ puts(_( // xgettext:no-c-format
1158
+ " --memlimit-compress=LIMIT\n"
1159
+ " --memlimit-decompress=LIMIT\n"
1160
+ " -M, --memlimit=LIMIT\n"
1161
+ " set memory usage limit for compression, decompression,\n"
1162
+ " or both; LIMIT is in bytes, % of RAM, or 0 for defaults"));
1163
+
1164
+ puts(_(
1165
+ " --no-adjust if compression settings exceed the memory usage limit,\n"
1166
+ " give an error instead of adjusting the settings downwards"));
1167
+ }
1168
+
1169
+ if (long_help) {
1170
+ puts(_(
1171
+ "\n Custom filter chain for compression (alternative for using presets):"));
1172
+
1173
+ #if defined(HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1) \
1174
+ || defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)
1175
+ // TRANSLATORS: The word "literal" in "literal context bits"
1176
+ // means how many "context bits" to use when encoding
1177
+ // literals. A literal is a single 8-bit byte. It doesn't
1178
+ // mean "literally" here.
1179
+ puts(_(
1180
+ "\n"
1181
+ " --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
1182
+ " --lzma2[=OPTS] more of the following options (valid values; default):\n"
1183
+ " preset=PRE reset options to a preset (0-9[e])\n"
1184
+ " dict=NUM dictionary size (4KiB - 1536MiB; 8MiB)\n"
1185
+ " lc=NUM number of literal context bits (0-4; 3)\n"
1186
+ " lp=NUM number of literal position bits (0-4; 0)\n"
1187
+ " pb=NUM number of position bits (0-4; 2)\n"
1188
+ " mode=MODE compression mode (fast, normal; normal)\n"
1189
+ " nice=NUM nice length of a match (2-273; 64)\n"
1190
+ " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
1191
+ " depth=NUM maximum search depth; 0=automatic (default)"));
1192
+ #endif
1193
+
1194
+ puts(_(
1195
+ "\n"
1196
+ " --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
1197
+ " --powerpc[=OPTS] PowerPC BCJ filter (big endian only)\n"
1198
+ " --ia64[=OPTS] IA-64 (Itanium) BCJ filter\n"
1199
+ " --arm[=OPTS] ARM BCJ filter (little endian only)\n"
1200
+ " --armthumb[=OPTS] ARM-Thumb BCJ filter (little endian only)\n"
1201
+ " --sparc[=OPTS] SPARC BCJ filter\n"
1202
+ " Valid OPTS for all BCJ filters:\n"
1203
+ " start=NUM start offset for conversions (default=0)"));
1204
+
1205
+ #if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)
1206
+ puts(_(
1207
+ "\n"
1208
+ " --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
1209
+ " dist=NUM distance between bytes being subtracted\n"
1210
+ " from each other (1-256; 1)"));
1211
+ #endif
1212
+ }
1213
+
1214
+ if (long_help)
1215
+ puts(_("\n Other options:\n"));
1216
+
1217
+ puts(_(
1218
+ " -q, --quiet suppress warnings; specify twice to suppress errors too\n"
1219
+ " -v, --verbose be verbose; specify twice for even more verbose"));
1220
+
1221
+ if (long_help) {
1222
+ puts(_(
1223
+ " -Q, --no-warn make warnings not affect the exit status"));
1224
+ puts(_(
1225
+ " --robot use machine-parsable messages (useful for scripts)"));
1226
+ puts("");
1227
+ puts(_(
1228
+ " --info-memory display the total amount of RAM and the currently active\n"
1229
+ " memory usage limits, and exit"));
1230
+ puts(_(
1231
+ " -h, --help display the short help (lists only the basic options)\n"
1232
+ " -H, --long-help display this long help and exit"));
1233
+ } else {
1234
+ puts(_(
1235
+ " -h, --help display this short help and exit\n"
1236
+ " -H, --long-help display the long help (lists also the advanced options)"));
1237
+ }
1238
+
1239
+ puts(_(
1240
+ " -V, --version display the version number and exit"));
1241
+
1242
+ puts(_("\nWith no FILE, or when FILE is -, read standard input.\n"));
1243
+
1244
+ // TRANSLATORS: This message indicates the bug reporting address
1245
+ // for this package. Please add _another line_ saying
1246
+ // "Report translation bugs to <...>\n" with the email or WWW
1247
+ // address for translation bugs. Thanks.
1248
+ printf(_("Report bugs to <%s> (in English or Finnish).\n"),
1249
+ PACKAGE_BUGREPORT);
1250
+ printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1251
+
1252
+ #if LZMA_VERSION_STABILITY != LZMA_VERSION_STABILITY_STABLE
1253
+ puts(_(
1254
+ "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."));
1255
+ #endif
1256
+
1257
+ tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
1258
+ }