diff options
Diffstat (limited to 'programs')
| -rw-r--r-- | programs/.gitignore | 1 | ||||
| -rw-r--r-- | programs/README.md | 4 | ||||
| -rw-r--r-- | programs/benchfn.c | 8 | ||||
| -rw-r--r-- | programs/fileio.c | 36 | ||||
| -rw-r--r-- | programs/fileio.h | 1 | ||||
| -rw-r--r-- | programs/util.c | 10 | ||||
| -rw-r--r-- | programs/zstd.1 | 6 | ||||
| -rw-r--r-- | programs/zstdcli.c | 51 | ||||
| -rwxr-xr-x | programs/zstdgrep | 9 | ||||
| -rw-r--r-- | programs/zstdgrep.1 | 2 | ||||
| -rw-r--r-- | programs/zstdless.1 | 2 |
11 files changed, 99 insertions, 31 deletions
diff --git a/programs/.gitignore b/programs/.gitignore index 701830c777c2..0a8e18fbb2f8 100644 --- a/programs/.gitignore +++ b/programs/.gitignore @@ -33,4 +33,5 @@ afl # Misc files *.bat +!windres/generate_res.bat dirTest* diff --git a/programs/README.md b/programs/README.md index afbebaa16fdf..d9ef5dd2a62e 100644 --- a/programs/README.md +++ b/programs/README.md @@ -37,7 +37,7 @@ There are however other Makefile targets that create different variations of CLI `.gz` support is automatically enabled when `zlib` library is detected at build time. It's possible to disable `.gz` support, by setting `HAVE_ZLIB=0`. Example : `make zstd HAVE_ZLIB=0` - It's also possible to force compilation with zlib support, `using HAVE_ZLIB=1`. + It's also possible to force compilation with zlib support, using `HAVE_ZLIB=1`. In which case, linking stage will fail if `zlib` library cannot be found. This is useful to prevent silent feature disabling. @@ -45,7 +45,7 @@ There are however other Makefile targets that create different variations of CLI This is ordered through commands `--format=xz` and `--format=lzma` respectively. Alternatively, symlinks named `xz`, `unxz`, `lzma`, or `unlzma` will mimic intended behavior. `.xz` and `.lzma` support is automatically enabled when `lzma` library is detected at build time. - It's possible to disable `.xz` and `.lzma` support, by setting `HAVE_LZMA=0` . + It's possible to disable `.xz` and `.lzma` support, by setting `HAVE_LZMA=0`. Example : `make zstd HAVE_LZMA=0` It's also possible to force compilation with lzma support, using `HAVE_LZMA=1`. In which case, linking stage will fail if `lzma` library cannot be found. diff --git a/programs/benchfn.c b/programs/benchfn.c index 0932d155de49..2a51a34ff110 100644 --- a/programs/benchfn.c +++ b/programs/benchfn.c @@ -15,7 +15,6 @@ ***************************************/ #include <stdlib.h> /* malloc, free */ #include <string.h> /* memset */ -#undef NDEBUG /* assert must not be disabled */ #include <assert.h> /* assert */ #include "timefn.h" /* UTIL_time_t, UTIL_getTime */ @@ -54,6 +53,9 @@ return retValue; \ } +/* Abort execution if a condition is not met */ +#define CONTROL(c) { if (!(c)) { DEBUGOUTPUT("error: %s \n", #c); abort(); } } + /* ************************************* * Benchmarking an arbitrary function @@ -68,13 +70,13 @@ int BMK_isSuccessful_runOutcome(BMK_runOutcome_t outcome) * check outcome validity first, using BMK_isValid_runResult() */ BMK_runTime_t BMK_extract_runTime(BMK_runOutcome_t outcome) { - assert(outcome.error_tag_never_ever_use_directly == 0); + CONTROL(outcome.error_tag_never_ever_use_directly == 0); return outcome.internal_never_ever_use_directly; } size_t BMK_extract_errorResult(BMK_runOutcome_t outcome) { - assert(outcome.error_tag_never_ever_use_directly != 0); + CONTROL(outcome.error_tag_never_ever_use_directly != 0); return outcome.error_result_never_ever_use_directly; } diff --git a/programs/fileio.c b/programs/fileio.c index 7ada5921b123..569a410c1a24 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -175,7 +175,7 @@ static void clearHandler(void) #if !defined(BACKTRACE_ENABLE) /* automatic detector : backtrace enabled by default on linux+glibc and osx */ -# if (defined(__linux__) && defined(__GLIBC__)) \ +# if (defined(__linux__) && (defined(__GLIBC__) && !defined(__UCLIBC__))) \ || (defined(__APPLE__) && defined(__MACH__)) # define BACKTRACE_ENABLE 1 # else @@ -269,6 +269,13 @@ void FIO_addAbortHandler() else return -1; } + static __int64 LONG_TELL(FILE* file) { + LARGE_INTEGER off, newOff; + off.QuadPart = 0; + newOff.QuadPart = 0; + SetFilePointerEx((HANDLE) _get_osfhandle(_fileno(file)), off, &newOff, FILE_CURRENT); + return newOff.QuadPart; + } #else # define LONG_SEEK fseek # define LONG_TELL ftell @@ -297,6 +304,7 @@ struct FIO_prefs_s { int ldmMinMatch; int ldmBucketSizeLog; int ldmHashRateLog; + size_t targetCBlockSize; ZSTD_literalCompressionMode_e literalCompressionMode; /* IO preferences */ @@ -341,6 +349,7 @@ FIO_prefs_t* FIO_createPreferences(void) ret->ldmMinMatch = 0; ret->ldmBucketSizeLog = FIO_LDM_PARAM_NOTSET; ret->ldmHashRateLog = FIO_LDM_PARAM_NOTSET; + ret->targetCBlockSize = 0; ret->literalCompressionMode = ZSTD_lcm_auto; return ret; } @@ -409,6 +418,10 @@ void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable) { prefs->rsyncable = rsyncable; } +void FIO_setTargetCBlockSize(FIO_prefs_t* const prefs, size_t targetCBlockSize) { + prefs->targetCBlockSize = targetCBlockSize; +} + void FIO_setLiteralCompressionMode( FIO_prefs_t* const prefs, ZSTD_literalCompressionMode_e mode) { @@ -557,8 +570,11 @@ static FILE* FIO_openDstFile(FIO_prefs_t* const prefs, const char* srcFileName, } } { FILE* const f = fopen( dstFileName, "wb" ); - if (f == NULL) + if (f == NULL) { DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); + } else { + chmod(dstFileName, 00600); + } return f; } } @@ -649,6 +665,8 @@ static cRess_t FIO_createCResources(FIO_prefs_t* const prefs, CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_checksumFlag, prefs->checksumFlag) ); /* compression level */ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, cLevel) ); + /* max compressed block size */ + CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_targetCBlockSize, (int)prefs->targetCBlockSize) ); /* long distance matching */ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_enableLongDistanceMatching, prefs->ldmFlag) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_ldmHashLog, prefs->ldmHashLog) ); @@ -1158,6 +1176,8 @@ FIO_compressFilename_internal(FIO_prefs_t* const prefs, const char* dstFileName, const char* srcFileName, int compressionLevel) { + UTIL_time_t const timeStart = UTIL_getTime(); + clock_t const cpuStart = clock(); U64 readsize = 0; U64 compressedfilesize = 0; U64 const fileSize = UTIL_getFileSize(srcFileName); @@ -1210,6 +1230,15 @@ FIO_compressFilename_internal(FIO_prefs_t* const prefs, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); + /* Elapsed Time and CPU Load */ + { clock_t const cpuEnd = clock(); + double const cpuLoad_s = (double)(cpuEnd - cpuStart) / CLOCKS_PER_SEC; + U64 const timeLength_ns = UTIL_clockSpanNano(timeStart); + double const timeLength_s = (double)timeLength_ns / 1000000000; + double const cpuLoad_pct = (cpuLoad_s / timeLength_s) * 100; + DISPLAYLEVEL(4, "%-20s : Completed in %.2f sec (cpu load : %.0f%%)\n", + srcFileName, timeLength_s, cpuLoad_pct); + } return 0; } @@ -1332,15 +1361,12 @@ int FIO_compressFilename(FIO_prefs_t* const prefs, const char* dictFileName, int compressionLevel, ZSTD_compressionParameters comprParams) { - clock_t const start = clock(); U64 const fileSize = UTIL_getFileSize(srcFileName); U64 const srcSize = (fileSize == UTIL_FILESIZE_UNKNOWN) ? ZSTD_CONTENTSIZE_UNKNOWN : fileSize; cRess_t const ress = FIO_createCResources(prefs, dictFileName, compressionLevel, srcSize, comprParams); int const result = FIO_compressFilename_srcFile(prefs, ress, dstFileName, srcFileName, compressionLevel); - double const seconds = (double)(clock() - start) / CLOCKS_PER_SEC; - DISPLAYLEVEL(4, "Completed in %.2f sec \n", seconds); FIO_freeCResources(ress); return result; diff --git a/programs/fileio.h b/programs/fileio.h index e46633752f4a..311f8c0e1f08 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -71,6 +71,7 @@ void FIO_setOverlapLog(FIO_prefs_t* const prefs, int overlapLog); void FIO_setRemoveSrcFile(FIO_prefs_t* const prefs, unsigned flag); void FIO_setSparseWrite(FIO_prefs_t* const prefs, unsigned sparse); /**< 0: no sparse; 1: disable on stdout; 2: always enabled */ void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable); +void FIO_setTargetCBlockSize(FIO_prefs_t* const prefs, size_t targetCBlockSize); void FIO_setLiteralCompressionMode( FIO_prefs_t* const prefs, ZSTD_literalCompressionMode_e mode); diff --git a/programs/util.c b/programs/util.c index 7b827d4536ad..6190bca50270 100644 --- a/programs/util.c +++ b/programs/util.c @@ -107,20 +107,12 @@ int UTIL_isSameFile(const char* file1, const char* file2) U32 UTIL_isLink(const char* infilename) { /* macro guards, as defined in : https://linux.die.net/man/2/lstat */ -#ifndef __STRICT_ANSI__ -#if defined(_BSD_SOURCE) \ - || (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) \ - || (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) \ - || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) \ - || (defined(__APPLE__) && defined(__MACH__)) \ - || defined(__OpenBSD__) \ - || defined(__FreeBSD__) +#if PLATFORM_POSIX_VERSION >= 200112L int r; stat_t statbuf; r = lstat(infilename, &statbuf); if (!r && S_ISLNK(statbuf.st_mode)) return 1; #endif -#endif (void)infilename; return 0; } diff --git a/programs/zstd.1 b/programs/zstd.1 index cb4e1271a0f2..beca9da421d1 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -1,5 +1,5 @@ . -.TH "ZSTD" "1" "December 2018" "zstd 1.3.8" "User Commands" +.TH "ZSTD" "1" "July 2019" "zstd 1.4.1" "User Commands" . .SH "NAME" \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files @@ -187,6 +187,10 @@ verbose mode suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\. . .TP +\fB\-\-no\-progress\fR +do not display the progress bar, but keep all other messages\. +. +.TP \fB\-C\fR, \fB\-\-[no\-]check\fR add integrity check computed from uncompressed data (default: enabled) . diff --git a/programs/zstdcli.c b/programs/zstdcli.c index fbb1c048a363..a13c924c5ce0 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -141,6 +141,7 @@ static int usage_advanced(const char* programName) DISPLAY( "--long[=#]: enable long distance matching with given window log (default: %u)\n", g_defaultMaxWindowLog); DISPLAY( "--fast[=#]: switch to ultra fast compression level (default: %u)\n", 1); DISPLAY( "--adapt : dynamically adapt compression level to I/O conditions \n"); + DISPLAY( "--target-compressed-block-size=# : make compressed block near targeted size \n"); #ifdef ZSTD_MULTITHREAD DISPLAY( " -T# : spawns # compression threads (default: 1, 0==# cores) \n"); DISPLAY( " -B# : select size of each job (default: 0==automatic) \n"); @@ -179,8 +180,8 @@ static int usage_advanced(const char* programName) DISPLAY( "\n"); DISPLAY( "Dictionary builder : \n"); DISPLAY( "--train ## : create a dictionary from a training set of files \n"); - DISPLAY( "--train-cover[=k=#,d=#,steps=#,split=#] : use the cover algorithm with optional args\n"); - DISPLAY( "--train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#] : use the fast cover algorithm with optional args\n"); + DISPLAY( "--train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]] : use the cover algorithm with optional args\n"); + DISPLAY( "--train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]] : use the fast cover algorithm with optional args\n"); DISPLAY( "--train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u)\n", g_defaultSelectivityLevel); DISPLAY( " -o file : `file` is dictionary name (default: %s) \n", g_defaultDictName); DISPLAY( "--maxdict=# : limit dictionary to specified size (default: %u) \n", g_defaultMaxDictSize); @@ -299,6 +300,7 @@ static unsigned longCommandWArg(const char** stringPtr, const char* longCommand) * @return 1 means that cover parameters were correct * @return 0 in case of malformed parameters */ +static const unsigned kDefaultRegression = 1; static unsigned parseCoverParameters(const char* stringPtr, ZDICT_cover_params_t* params) { memset(params, 0, sizeof(*params)); @@ -311,10 +313,23 @@ static unsigned parseCoverParameters(const char* stringPtr, ZDICT_cover_params_t params->splitPoint = (double)splitPercentage / 100.0; if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "shrink")) { + params->shrinkDictMaxRegression = kDefaultRegression; + params->shrinkDict = 1; + if (stringPtr[0]=='=') { + stringPtr++; + params->shrinkDictMaxRegression = readU32FromChar(&stringPtr); + } + if (stringPtr[0]==',') { + stringPtr++; + continue; + } + else break; + } return 0; } if (stringPtr[0] != 0) return 0; - DISPLAYLEVEL(4, "cover: k=%u\nd=%u\nsteps=%u\nsplit=%u\n", params->k, params->d, params->steps, (unsigned)(params->splitPoint * 100)); + DISPLAYLEVEL(4, "cover: k=%u\nd=%u\nsteps=%u\nsplit=%u\nshrink%u\n", params->k, params->d, params->steps, (unsigned)(params->splitPoint * 100), params->shrinkDictMaxRegression); return 1; } @@ -338,10 +353,23 @@ static unsigned parseFastCoverParameters(const char* stringPtr, ZDICT_fastCover_ params->splitPoint = (double)splitPercentage / 100.0; if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "shrink")) { + params->shrinkDictMaxRegression = kDefaultRegression; + params->shrinkDict = 1; + if (stringPtr[0]=='=') { + stringPtr++; + params->shrinkDictMaxRegression = readU32FromChar(&stringPtr); + } + if (stringPtr[0]==',') { + stringPtr++; + continue; + } + else break; + } return 0; } if (stringPtr[0] != 0) return 0; - DISPLAYLEVEL(4, "cover: k=%u\nd=%u\nf=%u\nsteps=%u\nsplit=%u\naccel=%u\n", params->k, params->d, params->f, params->steps, (unsigned)(params->splitPoint * 100), params->accel); + DISPLAYLEVEL(4, "cover: k=%u\nd=%u\nf=%u\nsteps=%u\nsplit=%u\naccel=%u\nshrink=%u\n", params->k, params->d, params->f, params->steps, (unsigned)(params->splitPoint * 100), params->accel, params->shrinkDictMaxRegression); return 1; } @@ -367,6 +395,8 @@ static ZDICT_cover_params_t defaultCoverParams(void) params.d = 8; params.steps = 4; params.splitPoint = 1.0; + params.shrinkDict = 0; + params.shrinkDictMaxRegression = kDefaultRegression; return params; } @@ -379,6 +409,8 @@ static ZDICT_fastCover_params_t defaultFastCoverParams(void) params.steps = 4; params.splitPoint = 0.75; /* different from default splitPoint of cover */ params.accel = DEFAULT_ACCEL; + params.shrinkDict = 0; + params.shrinkDictMaxRegression = kDefaultRegression; return params; } #endif @@ -555,6 +587,7 @@ int main(int argCount, const char* argv[]) const char* suffix = ZSTD_EXTENSION; unsigned maxDictSize = g_defaultMaxDictSize; unsigned dictID = 0; + size_t targetCBlockSize = 0; int dictCLevel = g_defaultDictCLevel; unsigned dictSelect = g_defaultSelectivityLevel; #ifdef UTIL_HAS_CREATEFILELIST @@ -588,11 +621,11 @@ int main(int argCount, const char* argv[]) /* preset behaviors */ if (exeNameMatch(programName, ZSTD_ZSTDMT)) nbWorkers=0, singleThread=0; if (exeNameMatch(programName, ZSTD_UNZSTD)) operation=zom_decompress; - if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; forceStdout=1; FIO_overwriteMode(prefs); outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */ - if (exeNameMatch(programName, ZSTD_ZCAT)) { operation=zom_decompress; forceStdout=1; FIO_overwriteMode(prefs); outFileName=stdoutmark; g_displayLevel=1; } /* behave like zcat, also supports multiple formats */ + if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */ + if (exeNameMatch(programName, ZSTD_ZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* behave like zcat, also supports multiple formats */ if (exeNameMatch(programName, ZSTD_GZ)) { suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like gzip */ if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; FIO_setRemoveSrcFile(prefs, 1); } /* behave like gunzip, also supports multiple formats */ - if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; forceStdout=1; FIO_overwriteMode(prefs); outFileName=stdoutmark; g_displayLevel=1; } /* behave like gzcat, also supports multiple formats */ + if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* behave like gzcat, also supports multiple formats */ if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; FIO_setCompressionType(prefs, FIO_lzmaCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like lzma */ if (exeNameMatch(programName, ZSTD_UNLZMA)) { operation=zom_decompress; FIO_setCompressionType(prefs, FIO_lzmaCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like unlzma, also supports multiple formats */ if (exeNameMatch(programName, ZSTD_XZ)) { suffix = XZ_EXTENSION; FIO_setCompressionType(prefs, FIO_xzCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like xz */ @@ -711,6 +744,7 @@ int main(int argCount, const char* argv[]) if (longCommandWArg(&argument, "--maxdict=")) { maxDictSize = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--dictID=")) { dictID = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--zstd=")) { if (!parseCompressionParameters(argument, &compressionParams)) CLEAN_RETURN(badusage(programName)); continue; } + if (longCommandWArg(&argument, "--target-compressed-block-size=")) { targetCBlockSize = readU32FromChar(&argument); continue; } if (longCommandWArg(&argument, "--long")) { unsigned ldmWindowLog = 0; ldmFlag = 1; @@ -1115,6 +1149,7 @@ int main(int argCount, const char* argv[]) FIO_setAdaptMin(prefs, adaptMin); FIO_setAdaptMax(prefs, adaptMax); FIO_setRsyncable(prefs, rsyncable); + FIO_setTargetCBlockSize(prefs, targetCBlockSize); FIO_setLiteralCompressionMode(prefs, literalCompressionMode); if (adaptMin > cLevel) cLevel = adaptMin; if (adaptMax < cLevel) cLevel = adaptMax; @@ -1124,7 +1159,7 @@ int main(int argCount, const char* argv[]) else operationResult = FIO_compressMultipleFilenames(prefs, filenameTable, filenameIdx, outFileName, suffix, dictFileName, cLevel, compressionParams); #else - (void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; /* not used when ZSTD_NOCOMPRESS set */ + (void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; (void)targetCBlockSize; /* not used when ZSTD_NOCOMPRESS set */ DISPLAY("Compression not supported \n"); #endif } else { /* decompression or test */ diff --git a/programs/zstdgrep b/programs/zstdgrep index cb804b8bead4..4879fb0dae49 100755 --- a/programs/zstdgrep +++ b/programs/zstdgrep @@ -58,6 +58,9 @@ while [ "$#" -gt 0 ] && [ "${endofopts}" -eq 0 ]; do shift 2 break ;; + -f) + pattern_found=2 + ;; *) ;; esac @@ -117,7 +120,11 @@ else set -f while [ "$#" -gt 0 ]; do # shellcheck disable=SC2086 - "${zcat}" -fq -- "$1" | "${grep}" --label="${1}" ${grep_args} -- "${pattern}" - + if [ $pattern_found -eq 2 ]; then + "${zcat}" -fq -- "$1" | "${grep}" --label="${1}" ${grep_args} -- - + else + "${zcat}" -fq -- "$1" | "${grep}" --label="${1}" ${grep_args} -- "${pattern}" - + fi [ "$?" -ne 0 ] && EXIT_CODE=1 shift done diff --git a/programs/zstdgrep.1 b/programs/zstdgrep.1 index 57bc14de3587..d0a0292215a5 100644 --- a/programs/zstdgrep.1 +++ b/programs/zstdgrep.1 @@ -1,5 +1,5 @@ . -.TH "ZSTDGREP" "1" "December 2018" "zstd 1.3.8" "User Commands" +.TH "ZSTDGREP" "1" "July 2019" "zstd 1.4.1" "User Commands" . .SH "NAME" \fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files diff --git a/programs/zstdless.1 b/programs/zstdless.1 index ff39742bf8a6..4e21d5a90637 100644 --- a/programs/zstdless.1 +++ b/programs/zstdless.1 @@ -1,5 +1,5 @@ . -.TH "ZSTDLESS" "1" "December 2018" "zstd 1.3.8" "User Commands" +.TH "ZSTDLESS" "1" "July 2019" "zstd 1.4.1" "User Commands" . .SH "NAME" \fBzstdless\fR \- view zstandard\-compressed files |
