aboutsummaryrefslogtreecommitdiff
path: root/programs
diff options
context:
space:
mode:
Diffstat (limited to 'programs')
-rw-r--r--programs/.gitignore4
-rw-r--r--programs/Makefile39
-rw-r--r--programs/README.md45
-rw-r--r--programs/bench.c8
-rw-r--r--programs/bench.h8
-rw-r--r--programs/datagen.c8
-rw-r--r--programs/datagen.h10
-rw-r--r--programs/dibio.c8
-rw-r--r--programs/dibio.h8
-rw-r--r--programs/fileio.c467
-rw-r--r--programs/fileio.h8
-rw-r--r--programs/platform.h12
-rw-r--r--programs/util.h12
-rw-r--r--programs/zstd.16
-rw-r--r--programs/zstd.1.md5
-rw-r--r--programs/zstdcli.c106
16 files changed, 410 insertions, 344 deletions
diff --git a/programs/.gitignore b/programs/.gitignore
index eeaf051d6edf..701830c777c2 100644
--- a/programs/.gitignore
+++ b/programs/.gitignore
@@ -1,8 +1,12 @@
# local binary (Makefile)
zstd
zstd32
+zstd4
zstd-compress
zstd-decompress
+zstd-frugal
+zstd-small
+zstd-nolegacy
# Object files
*.o
diff --git a/programs/Makefile b/programs/Makefile
index 8b080d446606..c5469cfc4def 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -39,9 +39,10 @@ endif
CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
-I$(ZSTDDIR)/dictBuilder \
+ -DZSTD_NEWAPI \
-DXXH_NAMESPACE=ZSTD_ # because xxhash.o already compiled with this macro from library
CFLAGS ?= -O3
-DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
+DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
-Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
@@ -131,12 +132,15 @@ else
LZ4_MSG := $(NO_LZ4_MSG)
endif
-.PHONY: default all clean clean_decomp_o install uninstall generate_res
-
+.PHONY: default
default: zstd-release
+.PHONY: all
all: zstd
+.PHONY: allVariants
+allVariants: zstd zstd-compress zstd-decompress zstd-small zstd-nolegacy
+
$(ZSTDDECOMP_O): CFLAGS += $(ALIGN_LOOP)
zstd zstd4 : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP) $(LZMACPP)
@@ -153,8 +157,9 @@ zstd zstd4 : $(ZSTDLIB_FILES) zstdcli.o fileio.o bench.o datagen.o dibio.o
ifneq (,$(filter Windows%,$(OS)))
windres/generate_res.bat
endif
- $(CC) $(FLAGS) $^ $(RES_FILE) -o zstd$(EXT) $(LDFLAGS)
+ $(CC) $(FLAGS) $^ $(RES_FILE) -o $@$(EXT) $(LDFLAGS)
+.PHONY: zstd-release
zstd-release: DEBUGFLAGS :=
zstd-release: zstd
@@ -165,8 +170,8 @@ ifneq (,$(filter Windows%,$(OS)))
endif
$(CC) -m32 $(FLAGS) $^ $(RES32_FILE) -o $@$(EXT)
-zstd-nolegacy : clean_decomp_o
- $(MAKE) zstd ZSTD_LEGACY_SUPPORT=0
+zstd-nolegacy : $(ZSTD_FILES) $(ZDICT_FILES) zstdcli.o fileio.c bench.o datagen.o dibio.o
+ $(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS)
zstd-nomt : THREAD_CPP :=
zstd-nomt : THREAD_LD :=
@@ -197,9 +202,9 @@ zstd-pgo : clean zstd
$(MAKE) zstd MOREFLAGS=-fprofile-use
# minimal target, with only zstd compression and decompression. no bench. no legacy.
-zstd-small: CFLAGS = "-Os -s"
+zstd-small: CFLAGS = -Os -s
zstd-frugal zstd-small: $(ZSTD_FILES) zstdcli.c fileio.c
- $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o zstd$(EXT)
+ $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT $^ -o $@$(EXT)
zstd-decompress: $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) zstdcli.c fileio.c
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS $^ -o $@$(EXT)
@@ -207,34 +212,37 @@ zstd-decompress: $(ZSTDCOMMON_FILES) $(ZSTDDECOMP_FILES) zstdcli.c fileio.c
zstd-compress: $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) zstdcli.c fileio.c
$(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS $^ -o $@$(EXT)
-# zstd is now built with Multi-threading by default
+# zstd is now built with multithreading enabled y default
zstdmt: zstd
+.PHONY: generate_res
generate_res:
windres/generate_res.bat
+.PHONY: clean
clean:
$(MAKE) -C $(ZSTDDIR) clean
@$(RM) $(ZSTDDIR)/decompress/*.o $(ZSTDDIR)/decompress/zstd_decompress.gcda
@$(RM) core *.o tmp* result* *.gcda dictionary *.zst \
zstd$(EXT) zstd32$(EXT) zstd-compress$(EXT) zstd-decompress$(EXT) \
+ zstd-small$(EXT) zstd-frugal$(EXT) zstd-nolegacy$(EXT) zstd4$(EXT) \
*.gcda default.profraw have_zlib$(EXT)
@echo Cleaning completed
-clean_decomp_o:
- @$(RM) $(ZSTDDECOMP_O)
-
MD2ROFF = ronn
MD2ROFF_FLAGS = --roff --warnings --manual="User Commands" --organization="zstd $(ZSTD_VERSION)"
zstd.1: zstd.1.md
cat $^ | $(MD2ROFF) $(MD2ROFF_FLAGS) | sed -n '/^\.\\\".*/!p' > $@
+.PHONY: man
man: zstd.1
+.PHONY: clean-man
clean-man:
rm zstd.1
+.PHONY: preview-man
preview-man: clean-man man
man ./zstd.1
@@ -243,6 +251,10 @@ preview-man: clean-man man
#-----------------------------------------------------------------------------
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS))
+.PHONY: list
+list:
+ @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs
+
ifneq (,$(filter $(shell uname),SunOS))
INSTALL ?= ginstall
else
@@ -263,6 +275,7 @@ INSTALL_PROGRAM ?= $(INSTALL) -m 755
INSTALL_SCRIPT ?= $(INSTALL) -m 755
INSTALL_MAN ?= $(INSTALL) -m 644
+.PHONY: install
install: zstd
@echo Installing binaries
@$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/
@@ -278,6 +291,7 @@ install: zstd
@ln -sf zstd.1 $(DESTDIR)$(MANDIR)/unzstd.1
@echo zstd installation completed
+.PHONY: uninstall
uninstall:
@$(RM) $(DESTDIR)$(BINDIR)/zstdgrep
@$(RM) $(DESTDIR)$(BINDIR)/zstdless
@@ -288,4 +302,5 @@ uninstall:
@$(RM) $(DESTDIR)$(MANDIR)/unzstd.1
@$(RM) $(DESTDIR)$(MANDIR)/zstd.1
@echo zstd programs successfully uninstalled
+
endif
diff --git a/programs/README.md b/programs/README.md
index bd8fba069952..8b65dfdb3f24 100644
--- a/programs/README.md
+++ b/programs/README.md
@@ -3,44 +3,54 @@ Command Line Interface for Zstandard library
Command Line Interface (CLI) can be created using the `make` command without any additional parameters.
There are however other Makefile targets that create different variations of CLI:
-- `zstd` : default CLI supporting gzip-like arguments; includes dictionary builder, benchmark, and support for decompression of legacy zstd versions
-- `zstd32` : Same as `zstd`, but forced to compile in 32-bits mode
-- `zstd_nolegacy` : Same as `zstd` except of support for decompression of legacy zstd versions
-- `zstd-small` : CLI optimized for minimal size; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
-- `zstd-compress` : compressor-only version of CLI; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
-- `zstd-decompress` : decompressor-only version of CLI; without dictionary builder, benchmark, and support for decompression of legacy zstd versions
+- `zstd` : default CLI supporting gzip-like arguments; includes dictionary builder, benchmark, and support for decompression of legacy zstd formats
+- `zstd_nolegacy` : Same as `zstd` but without support for legacy zstd formats
+- `zstd-small` : CLI optimized for minimal size; no dictionary builder, no benchmark, and no support for legacy zstd formats
+- `zstd-compress` : version of CLI which can only compress into zstd format
+- `zstd-decompress` : version of CLI which can only decompress zstd format
#### Compilation variables
-`zstd` tries to detect and use the following features automatically :
+`zstd` scope can be altered by modifying the following compilation variables :
- __HAVE_THREAD__ : multithreading is automatically enabled when `pthread` is detected.
- It's possible to disable multithread support, by either compiling `zstd-nomt` target or using HAVE_THREAD=0 variable.
+ It's possible to disable multithread support, by setting HAVE_THREAD=0 .
Example : make zstd HAVE_THREAD=0
It's also possible to force compilation with multithread support, using HAVE_THREAD=1.
In which case, linking stage will fail if `pthread` library cannot be found.
This might be useful to prevent silent feature disabling.
- __HAVE_ZLIB__ : `zstd` can compress and decompress files in `.gz` format.
- This is done through command `--format=gzip`.
+ This is ordered through command `--format=gzip`.
Alternatively, symlinks named `gzip` or `gunzip` will mimic intended behavior.
`.gz` support is automatically enabled when `zlib` library is detected at build time.
- It's possible to disable `.gz` support, by either compiling `zstd-nogz` target or using HAVE_ZLIB=0 variable.
+ 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.
In which case, linking stage will fail if `zlib` library cannot be found.
This might be useful to prevent silent feature disabling.
- __HAVE_LZMA__ : `zstd` can compress and decompress files in `.xz` and `.lzma` formats.
- This is done through commands `--format=xz` and `--format=lzma` respectively.
+ 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 either compiling `zstd-noxz` target or using HAVE_LZMA=0 variable.
+ 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.
This might be useful to prevent silent feature disabling.
+- __ZSTD_LEGACY_SUPPORT__ : `zstd` can decompress files compressed by older versions of `zstd`.
+ Starting v0.8.0, all versions of `zstd` produce frames compliant with the [specification](../doc/zstd_compression_format.md), and are therefore compatible.
+ But older versions (< v0.8.0) produced different, incompatible, frames.
+ By default, `zstd` supports decoding legacy formats >= v0.4.0 (`ZSTD_LEGACY_SUPPORT=4`).
+ This can be altered by modifying this compilation variable.
+ `ZSTD_LEGACY_SUPPORT=1` means "support all formats >= v0.1.0".
+ `ZSTD_LEGACY_SUPPORT=2` means "support all formats >= v0.2.0", and so on.
+ `ZSTD_LEGACY_SUPPORT=0` means _DO NOT_ support any legacy format.
+ if `ZSTD_LEGACY_SUPPORT >= 8`, it's the same as `0`, since there is no legacy format after `7`.
+ Note : `zstd` only supports decoding older formats, and cannot generate any legacy format.
+
#### Aggregation of parameters
CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined into `-b1e18i1`.
@@ -61,7 +71,7 @@ will rely more and more on previously decoded content to compress the rest of th
Usage of the dictionary builder and created dictionaries with CLI:
-1. Create the dictionary : `zstd --train FullPathToTrainingSet/* -o dictionaryName`
+1. Create the dictionary : `zstd --train PathToTrainingSet/* -o dictionaryName`
2. Compress with the dictionary: `zstd FILE -D dictionaryName`
3. Decompress with the dictionary: `zstd --decompress FILE.zst -D dictionaryName`
@@ -70,8 +80,8 @@ Usage of the dictionary builder and created dictionaries with CLI:
CLI includes in-memory compression benchmark module for zstd.
The benchmark is conducted using given filenames. The files are read into memory and joined together.
It makes benchmark more precise as it eliminates I/O overhead.
-Many filenames can be supplied as multiple parameters, parameters with wildcards or
-names of directories can be used as parameters with the `-r` option.
+Multiple filenames can be supplied, as multiple parameters, with wildcards,
+or names of directories can be used as parameters with `-r` option.
The benchmark measures ratio, compressed size, compression and decompression speed.
One can select compression levels starting from `-b` and ending with `-e`.
@@ -101,13 +111,14 @@ Advanced arguments :
-v : verbose mode; specify multiple times to increase verbosity
-q : suppress warnings; specify twice to suppress errors too
-c : force write to standard output, even if it is the console
+ -l : print information about zstd compressed files
--ultra : enable levels beyond 19, up to 22 (requires more memory)
- -T# : use # threads for compression (default:1)
- -B# : select size of each job (default:0==automatic)
--no-dictID : don't write dictID into header (dictionary compression)
--[no-]check : integrity check (default:enabled)
-r : operate recursively on directories
--format=gzip : compress files to the .gz format
+--format=xz : compress files to the .xz format
+--format=lzma : compress files to the .lzma format
--test : test compressed file integrity
--[no-]sparse : sparse mode (default:disabled)
-M# : Set a memory usage limit for decompression
diff --git a/programs/bench.c b/programs/bench.c
index f9493e3b0707..2b48a4663a86 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/programs/bench.h b/programs/bench.h
index 77a527f8ff82..5f8d61a25b30 100644
--- a/programs/bench.h
+++ b/programs/bench.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/programs/datagen.c b/programs/datagen.c
index d0116b97232f..b1da8e78b31e 100644
--- a/programs/datagen.c
+++ b/programs/datagen.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/programs/datagen.h b/programs/datagen.h
index 094056b696ca..5b1b7c47cc5d 100644
--- a/programs/datagen.h
+++ b/programs/datagen.h
@@ -1,11 +1,13 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
+
+
#ifndef DATAGEN_H
#define DATAGEN_H
diff --git a/programs/dibio.c b/programs/dibio.c
index 31cde5c95db1..ab2dc285a273 100644
--- a/programs/dibio.c
+++ b/programs/dibio.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/programs/dibio.h b/programs/dibio.h
index 84f7d580283d..0227239b26db 100644
--- a/programs/dibio.h
+++ b/programs/dibio.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/* This library is designed for a single-threaded console application.
diff --git a/programs/fileio.c b/programs/fileio.c
index 1dd8008e8495..65b4c7579194 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
@@ -925,230 +925,6 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
return result;
}
-typedef struct {
- int numActualFrames;
- int numSkippableFrames;
- unsigned long long decompressedSize;
- int decompUnavailable;
- unsigned long long compressedSize;
- int usesCheck;
-} fileInfo_t;
-
-/*
- * Reads information from file, stores in *info
- * if successful, returns 0, returns 1 for frame analysis error, returns 2 for file not compressed with zstd
- * returns 3 for cases in which file could not be opened.
- */
-static int getFileInfo(fileInfo_t* info, const char* inFileName){
- int detectError = 0;
- FILE* const srcFile = FIO_openSrcFile(inFileName);
- if (srcFile == NULL) {
- DISPLAY("Error: could not open source file %s\n", inFileName);
- return 3;
- }
- info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName);
- /* begin analyzing frame */
- for ( ; ; ) {
- BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
- size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile);
- if (numBytesRead < ZSTD_frameHeaderSize_min) {
- if (feof(srcFile) && numBytesRead == 0 && info->compressedSize > 0) {
- break;
- }
- else if (feof(srcFile)) {
- DISPLAY("Error: reached end of file with incomplete frame\n");
- detectError = 2;
- break;
- }
- else {
- DISPLAY("Error: did not reach end of file but ran out of frames\n");
- detectError = 1;
- break;
- }
- }
- {
- U32 const magicNumber = MEM_readLE32(headerBuffer);
- if (magicNumber == ZSTD_MAGICNUMBER) {
- U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead);
- if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) {
- info->decompUnavailable = 1;
- }
- else {
- info->decompressedSize += frameContentSize;
- }
- {
- /* move to the end of the frame header */
- size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead);
- if (ZSTD_isError(headerSize)) {
- DISPLAY("Error: could not determine frame header size\n");
- detectError = 1;
- break;
- }
- {
- int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR);
- if (ret != 0) {
- DISPLAY("Error: could not move to end of frame header\n");
- detectError = 1;
- break;
- }
- }
- }
-
- /* skip the rest of the blocks in the frame */
- {
- int lastBlock = 0;
- do {
- BYTE blockHeaderBuffer[3];
- U32 blockHeader;
- int blockSize;
- size_t const readBytes = fread(blockHeaderBuffer, 1, 3, srcFile);
- if (readBytes != 3) {
- DISPLAY("There was a problem reading the block header\n");
- detectError = 1;
- break;
- }
- blockHeader = MEM_readLE24(blockHeaderBuffer);
- lastBlock = blockHeader & 1;
- blockSize = blockHeader >> 3;
- {
- int const ret = fseek(srcFile, blockSize, SEEK_CUR);
- if (ret != 0) {
- DISPLAY("Error: could not skip to end of block\n");
- detectError = 1;
- break;
- }
- }
- } while (lastBlock != 1);
-
- if (detectError) {
- break;
- }
- }
- {
- /* check if checksum is used */
- BYTE const frameHeaderDescriptor = headerBuffer[4];
- int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2;
- if (contentChecksumFlag) {
- int const ret = fseek(srcFile, 4, SEEK_CUR);
- info->usesCheck = 1;
- if (ret != 0) {
- DISPLAY("Error: could not skip past checksum\n");
- detectError = 1;
- break;
- }
- }
- }
- info->numActualFrames++;
- }
- else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) {
- BYTE frameSizeBuffer[4];
- size_t const readBytes = fread(frameSizeBuffer, 1, 4, srcFile);
- if (readBytes != 4) {
- DISPLAY("There was an error reading skippable frame size");
- detectError = 1;
- break;
- }
- {
- U32 const frameSize = MEM_readLE32(frameSizeBuffer);
- int const ret = LONG_SEEK(srcFile, frameSize, SEEK_CUR);
- if (ret != 0) {
- DISPLAY("Error: could not find end of skippable frame\n");
- detectError = 1;
- break;
- }
- }
- info->numSkippableFrames++;
- }
- else {
- detectError = 2;
- break;
- }
- }
- }
- fclose(srcFile);
- return detectError;
-}
-
-static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){
- double const compressedSizeMB = (double)info->compressedSize/(1 MB);
- double const decompressedSizeMB = (double)info->decompressedSize/(1 MB);
- double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/info->compressedSize;
- const char* const checkString = (info->usesCheck ? "XXH64" : "None");
- if (displayLevel <= 2) {
- if (!info->decompUnavailable) {
- DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n");
- DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %5s %s\n",
- info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB,
- ratio, checkString, inFileName);
- }
- else {
- DISPLAYOUT("Skippable Non-Skippable Compressed Check Filename\n");
- DISPLAYOUT("%9d %13d %7.2f MB %5s %s\n",
- info->numSkippableFrames, info->numActualFrames, compressedSizeMB, checkString, inFileName);
- }
- }
- else{
- DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames);
- DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames);
- DISPLAYOUT("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize);
- if (!info->decompUnavailable) {
- DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize);
- DISPLAYOUT("Ratio: %.4f\n", ratio);
- }
- DISPLAYOUT("Check: %s\n", checkString);
- DISPLAYOUT("\n");
- }
-}
-
-
-static int FIO_listFile(const char* inFileName, int displayLevel, unsigned fileNo, unsigned numFiles){
- /* initialize info to avoid warnings */
- fileInfo_t info;
- memset(&info, 0, sizeof(info));
- DISPLAYOUT("%s (%u/%u):\n", inFileName, fileNo, numFiles);
- {
- int const error = getFileInfo(&info, inFileName);
- if (error == 1) {
- /* display error, but provide output */
- DISPLAY("An error occurred with getting file info\n");
- }
- else if (error == 2) {
- DISPLAYOUT("File %s not compressed with zstd\n", inFileName);
- if (displayLevel > 2) {
- DISPLAYOUT("\n");
- }
- return 1;
- }
- else if (error == 3) {
- /* error occurred with opening the file */
- if (displayLevel > 2) {
- DISPLAYOUT("\n");
- }
- return 1;
- }
- displayInfo(inFileName, &info, displayLevel);
- return error;
- }
-}
-
-int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int displayLevel){
- if (numFiles == 0) {
- DISPLAYOUT("No files given\n");
- return 0;
- }
- DISPLAYOUT("===========================================\n");
- DISPLAYOUT("Printing information about compressed files\n");
- DISPLAYOUT("===========================================\n");
- DISPLAYOUT("Number of files listed: %u\n", numFiles);
- {
- int error = 0;
- unsigned u;
- for (u=0; u<numFiles;u++) {
- error |= FIO_listFile(filenameTable[u], displayLevel, u+1, numFiles);
- }
- return error;
- }
-}
int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFiles,
const char* suffix,
@@ -1194,10 +970,8 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
missed_files += FIO_compressFilename_dstFile(ress, dstFileName, inFileNamesTable[u], compressionLevel);
} }
- /* Close & Free */
FIO_freeCResources(ress);
free(dstFileName);
-
return missed_files;
}
@@ -1208,8 +982,8 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
#ifndef ZSTD_NODECOMPRESS
/* **************************************************************************
-* Decompression
-****************************************************************************/
+ * Decompression
+ ***************************************************************************/
typedef struct {
void* srcBuffer;
size_t srcBufferLoaded;
@@ -1616,7 +1390,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
/* Write Block */
if (decodedBytes) {
if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) {
- DISPLAYLEVEL(1, "zstd: %s \n", strerr(errno));
+ DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno));
decodingError = 1; break;
}
filesize += decodedBytes;
@@ -1878,4 +1652,231 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles
return missingFiles + skippedFiles;
}
+
+
+/* **************************************************************************
+ * .zst file info (--list command)
+ ***************************************************************************/
+
+typedef struct {
+ int numActualFrames;
+ int numSkippableFrames;
+ unsigned long long decompressedSize;
+ int decompUnavailable;
+ unsigned long long compressedSize;
+ int usesCheck;
+} fileInfo_t;
+
+/** getFileInfo() :
+ * Reads information from file, stores in *info
+ * @return : 0 if successful
+ * 1 for frame analysis error
+ * 2 for file not compressed with zstd
+ * 3 for cases in which file could not be opened.
+ */
+static int getFileInfo(fileInfo_t* info, const char* inFileName){
+ int detectError = 0;
+ FILE* const srcFile = FIO_openSrcFile(inFileName);
+ if (srcFile == NULL) {
+ DISPLAY("Error: could not open source file %s\n", inFileName);
+ return 3;
+ }
+ info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName);
+
+ /* begin analyzing frame */
+ for ( ; ; ) {
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
+ size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile);
+ if (numBytesRead < ZSTD_frameHeaderSize_min) {
+ if (feof(srcFile) && numBytesRead == 0 && info->compressedSize > 0) {
+ break;
+ }
+ else if (feof(srcFile)) {
+ DISPLAY("Error: reached end of file with incomplete frame\n");
+ detectError = 2;
+ break;
+ }
+ else {
+ DISPLAY("Error: did not reach end of file but ran out of frames\n");
+ detectError = 1;
+ break;
+ }
+ }
+ { U32 const magicNumber = MEM_readLE32(headerBuffer);
+ /* Zstandard frame */
+ if (magicNumber == ZSTD_MAGICNUMBER) {
+ U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead);
+ if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) {
+ info->decompUnavailable = 1;
+ } else {
+ info->decompressedSize += frameContentSize;
+ }
+ /* move to the end of the frame header */
+ { size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead);
+ if (ZSTD_isError(headerSize)) {
+ DISPLAY("Error: could not determine frame header size\n");
+ detectError = 1;
+ break;
+ }
+ { int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR);
+ if (ret != 0) {
+ DISPLAY("Error: could not move to end of frame header\n");
+ detectError = 1;
+ break;
+ } } }
+
+ /* skip the rest of the blocks in the frame */
+ { int lastBlock = 0;
+ do {
+ BYTE blockHeaderBuffer[3];
+ size_t const readBytes = fread(blockHeaderBuffer, 1, 3, srcFile);
+ if (readBytes != 3) {
+ DISPLAY("There was a problem reading the block header\n");
+ detectError = 1;
+ break;
+ }
+ { U32 const blockHeader = MEM_readLE24(blockHeaderBuffer);
+ U32 const blockTypeID = (blockHeader >> 1) & 3;
+ U32 const isRLE = (blockTypeID == 1);
+ U32 const isWrongBlock = (blockTypeID == 3);
+ long const blockSize = isRLE ? 1 : (long)(blockHeader >> 3);
+ if (isWrongBlock) {
+ DISPLAY("Error: unsupported block type \n");
+ detectError = 1;
+ break;
+ }
+ lastBlock = blockHeader & 1;
+ { int const ret = fseek(srcFile, blockSize, SEEK_CUR);
+ if (ret != 0) {
+ DISPLAY("Error: could not skip to end of block\n");
+ detectError = 1;
+ break;
+ } } }
+ } while (lastBlock != 1);
+
+ if (detectError) break;
+ }
+
+ /* check if checksum is used */
+ { BYTE const frameHeaderDescriptor = headerBuffer[4];
+ int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2;
+ if (contentChecksumFlag) {
+ int const ret = fseek(srcFile, 4, SEEK_CUR);
+ info->usesCheck = 1;
+ if (ret != 0) {
+ DISPLAY("Error: could not skip past checksum\n");
+ detectError = 1;
+ break;
+ } } }
+ info->numActualFrames++;
+ }
+ /* Skippable frame */
+ else if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+ U32 const frameSize = MEM_readLE32(headerBuffer + 4);
+ long const seek = (long)(8 + frameSize - numBytesRead);
+ int const ret = LONG_SEEK(srcFile, seek, SEEK_CUR);
+ if (ret != 0) {
+ DISPLAY("Error: could not find end of skippable frame\n");
+ detectError = 1;
+ break;
+ }
+ info->numSkippableFrames++;
+ }
+ /* unknown content */
+ else {
+ detectError = 2;
+ break;
+ }
+ }
+ } /* end analyzing frame */
+ fclose(srcFile);
+ return detectError;
+}
+
+static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){
+ unsigned const unit = info->compressedSize < (1 MB) ? (1 KB) : (1 MB);
+ const char* const unitStr = info->compressedSize < (1 MB) ? "KB" : "MB";
+ double const compressedSizeUnit = (double)info->compressedSize / unit;
+ double const decompressedSizeUnit = (double)info->decompressedSize / unit;
+ double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/info->compressedSize;
+ const char* const checkString = (info->usesCheck ? "XXH64" : "None");
+ if (displayLevel <= 2) {
+ if (!info->decompUnavailable) {
+ DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n");
+ DISPLAYOUT("%9d %13d %7.2f %2s %9.2f %2s %5.3f %5s %s\n",
+ info->numSkippableFrames, info->numActualFrames,
+ compressedSizeUnit, unitStr, decompressedSizeUnit, unitStr,
+ ratio, checkString, inFileName);
+ } else {
+ DISPLAYOUT("Skippable Non-Skippable Compressed Check Filename\n");
+ DISPLAYOUT("%9d %13d %7.2f MB %5s %s\n",
+ info->numSkippableFrames, info->numActualFrames,
+ compressedSizeUnit, checkString, inFileName);
+ }
+ } else {
+ DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames);
+ DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames);
+ DISPLAYOUT("Compressed Size: %.2f %2s (%llu B)\n",
+ compressedSizeUnit, unitStr, info->compressedSize);
+ if (!info->decompUnavailable) {
+ DISPLAYOUT("Decompressed Size: %.2f %2s (%llu B)\n",
+ decompressedSizeUnit, unitStr, info->decompressedSize);
+ DISPLAYOUT("Ratio: %.4f\n", ratio);
+ }
+ DISPLAYOUT("Check: %s\n", checkString);
+ DISPLAYOUT("\n");
+ }
+}
+
+
+static int FIO_listFile(const char* inFileName, int displayLevel, unsigned fileNo, unsigned numFiles){
+ /* initialize info to avoid warnings */
+ fileInfo_t info;
+ memset(&info, 0, sizeof(info));
+ DISPLAYOUT("%s (%u/%u):\n", inFileName, fileNo, numFiles);
+ {
+ int const error = getFileInfo(&info, inFileName);
+ if (error == 1) {
+ /* display error, but provide output */
+ DISPLAY("An error occurred with getting file info\n");
+ }
+ else if (error == 2) {
+ DISPLAYOUT("File %s not compressed with zstd\n", inFileName);
+ if (displayLevel > 2) {
+ DISPLAYOUT("\n");
+ }
+ return 1;
+ }
+ else if (error == 3) {
+ /* error occurred with opening the file */
+ if (displayLevel > 2) {
+ DISPLAYOUT("\n");
+ }
+ return 1;
+ }
+ displayInfo(inFileName, &info, displayLevel);
+ return error;
+ }
+}
+
+int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int displayLevel){
+ if (numFiles == 0) {
+ DISPLAYOUT("No files given\n");
+ return 0;
+ }
+ DISPLAYOUT("===========================================\n");
+ DISPLAYOUT("Printing information about compressed files\n");
+ DISPLAYOUT("===========================================\n");
+ DISPLAYOUT("Number of files listed: %u\n", numFiles);
+ {
+ int error = 0;
+ unsigned u;
+ for (u=0; u<numFiles;u++) {
+ error |= FIO_listFile(filenameTable[u], displayLevel, u+1, numFiles);
+ }
+ return error;
+ }
+}
+
+
#endif /* #ifndef ZSTD_NODECOMPRESS */
diff --git a/programs/fileio.h b/programs/fileio.h
index 9d9167df9ef5..8008e97dd5f3 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/programs/platform.h b/programs/platform.h
index 74412cde332e..fb2e9b173d2a 100644
--- a/programs/platform.h
+++ b/programs/platform.h
@@ -1,12 +1,10 @@
-/**
- * platform.h - compiler and OS detection
- *
- * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#ifndef PLATFORM_H_MODULE
diff --git a/programs/util.h b/programs/util.h
index dd971e0f884b..7b553661cde3 100644
--- a/programs/util.h
+++ b/programs/util.h
@@ -1,12 +1,10 @@
-/**
- * util.h - utility functions
- *
- * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#ifndef UTIL_H_MODULE
diff --git a/programs/zstd.1 b/programs/zstd.1
index 5df45db2153e..5a91eea281f4 100644
--- a/programs/zstd.1
+++ b/programs/zstd.1
@@ -1,5 +1,5 @@
.
-.TH "ZSTD" "1" "June 2017" "zstd 1.3.0" "User Commands"
+.TH "ZSTD" "1" "August 2017" "zstd 1.3.1" "User Commands"
.
.SH "NAME"
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
@@ -105,7 +105,7 @@ unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note
.
.TP
\fB\-T#\fR, \fB\-\-threads=#\fR
-Compress using \fB#\fR threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
+Compress using \fB#\fR threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to ZSTDMT_NBTHREADS_MAX==256\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
.
.TP
\fB\-D file\fR
@@ -149,7 +149,7 @@ display help/long help and exit
.
.TP
\fB\-V\fR, \fB\-\-version\fR
-display version number and exit
+display version number and exit\. Advanced : \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\.
.
.TP
\fB\-v\fR
diff --git a/programs/zstd.1.md b/programs/zstd.1.md
index 24e25a2f3af1..4310afa1aaf8 100644
--- a/programs/zstd.1.md
+++ b/programs/zstd.1.md
@@ -108,6 +108,7 @@ the last one takes effect.
* `-T#`, `--threads=#`:
Compress using `#` threads (default: 1).
If `#` is 0, attempt to detect and use the number of physical CPU cores.
+ In all cases, the nb of threads is capped to ZSTDMT_NBTHREADS_MAX==256.
This modifier does nothing if `zstd` is compiled without multithread support.
* `-D file`:
use `file` as Dictionary to compress or decompress FILE(s)
@@ -139,7 +140,9 @@ the last one takes effect.
* `-h`/`-H`, `--help`:
display help/long help and exit
* `-V`, `--version`:
- display version number and exit
+ display version number and exit.
+ Advanced : `-vV` also displays supported formats.
+ `-vvV` also displays POSIX support.
* `-v`:
verbose mode
* `-q`, `--quiet`:
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index 35772e0a7140..e7eb71db6e37 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
@@ -16,7 +16,7 @@
#endif
#ifndef ZSTDCLI_CLEVEL_MAX
-# define ZSTDCLI_CLEVEL_MAX 19 /* when not using --ultra */
+# define ZSTDCLI_CLEVEL_MAX 19 /* without using --ultra */
#endif
@@ -26,14 +26,15 @@
**************************************/
#include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */
#include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
+#include <stdio.h> /* fprintf(), stdin, stdout, stderr */
#include <string.h> /* strcmp, strlen */
#include <errno.h> /* errno */
-#include "fileio.h"
+#include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */
#ifndef ZSTD_NOBENCH
# include "bench.h" /* BMK_benchFiles, BMK_SetNbSeconds */
#endif
#ifndef ZSTD_NODICT
-# include "dibio.h"
+# include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */
#endif
#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
#include "zstd.h" /* ZSTD_VERSION_STRING */
@@ -64,7 +65,7 @@
#define MB *(1 <<20)
#define GB *(1U<<30)
-#define DEFAULT_DISPLAY_LEVEL 2
+#define DISPLAY_LEVEL_DEFAULT 2
static const char* g_defaultDictName = "dictionary";
static const unsigned g_defaultMaxDictSize = 110 KB;
@@ -79,7 +80,7 @@ static U32 g_overlapLog = OVERLAP_LOG_DEFAULT;
**************************************/
#define DISPLAY(...) fprintf(g_displayOut, __VA_ARGS__)
#define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
-static int g_displayLevel = DEFAULT_DISPLAY_LEVEL; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
+static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
static FILE* g_displayOut;
@@ -88,12 +89,12 @@ static FILE* g_displayOut;
**************************************/
static int usage(const char* programName)
{
- DISPLAY( "Usage :\n");
- DISPLAY( " %s [args] [FILE(s)] [-o file]\n", programName);
+ DISPLAY( "Usage : \n");
+ DISPLAY( " %s [args] [FILE(s)] [-o file] \n", programName);
DISPLAY( "\n");
- DISPLAY( "FILE : a filename\n");
+ DISPLAY( "FILE : a filename \n");
DISPLAY( " with no FILE, or when FILE is - , read standard input\n");
- DISPLAY( "Arguments :\n");
+ DISPLAY( "Arguments : \n");
#ifndef ZSTD_NOCOMPRESS
DISPLAY( " -# : # compression level (1-%d, default:%d) \n", ZSTDCLI_CLEVEL_MAX, ZSTDCLI_CLEVEL_DEFAULT);
#endif
@@ -105,7 +106,7 @@ static int usage(const char* programName)
DISPLAY( " -f : overwrite output without prompting and (de)compress links \n");
DISPLAY( "--rm : remove source file(s) after successful de/compression \n");
DISPLAY( " -k : preserve source file(s) (default) \n");
- DISPLAY( " -h/-H : display help/long help and exit\n");
+ DISPLAY( " -h/-H : display help/long help and exit \n");
return 0;
}
@@ -114,12 +115,12 @@ static int usage_advanced(const char* programName)
DISPLAY(WELCOME_MESSAGE);
usage(programName);
DISPLAY( "\n");
- DISPLAY( "Advanced arguments :\n");
- DISPLAY( " -V : display Version number and exit\n");
+ DISPLAY( "Advanced arguments : \n");
+ DISPLAY( " -V : display Version number and exit \n");
DISPLAY( " -v : verbose mode; specify multiple times to increase verbosity\n");
DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");
DISPLAY( " -c : force write to standard output, even if it is the console\n");
- DISPLAY( " -l : print information about zstd compressed files.\n");
+ DISPLAY( " -l : print information about zstd compressed files \n");
#ifndef ZSTD_NOCOMPRESS
DISPLAY( "--ultra : enable levels beyond %i, up to %i (requires more memory)\n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
#ifdef ZSTD_MULTITHREAD
@@ -151,11 +152,10 @@ static int usage_advanced(const char* programName)
#endif
#endif
DISPLAY( " -M# : Set a memory usage limit for decompression \n");
- DISPLAY( "--list : list information about a zstd compressed file \n");
DISPLAY( "-- : All arguments after \"--\" are treated as files \n");
#ifndef ZSTD_NODICT
DISPLAY( "\n");
- DISPLAY( "Dictionary builder :\n");
+ DISPLAY( "Dictionary builder : \n");
DISPLAY( "--train ## : create a dictionary from a training set of files \n");
DISPLAY( "--train-cover[=k=#,d=#,steps=#] : use the cover algorithm with optional args\n");
DISPLAY( "--train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u)\n", g_defaultSelectivityLevel);
@@ -165,12 +165,12 @@ static int usage_advanced(const char* programName)
#endif
#ifndef ZSTD_NOBENCH
DISPLAY( "\n");
- DISPLAY( "Benchmark arguments :\n");
+ DISPLAY( "Benchmark arguments : \n");
DISPLAY( " -b# : benchmark file(s), using # compression level (default : 1) \n");
DISPLAY( " -e# : test all compression levels from -bX to # (default: 1)\n");
- DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s)\n");
+ DISPLAY( " -i# : minimum evaluation time in seconds (default : 3s) \n");
DISPLAY( " -B# : cut file into independent blocks of size # (default: no block)\n");
- DISPLAY( "--priority=rt : set process priority to real-time\n");
+ DISPLAY( "--priority=rt : set process priority to real-time \n");
#endif
return 0;
}
@@ -313,6 +313,35 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi
return 1;
}
+static void printVersion(void)
+{
+ DISPLAY(WELCOME_MESSAGE);
+ /* format support */
+ DISPLAYLEVEL(3, "*** supports: zstd");
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>0) && (ZSTD_LEGACY_SUPPORT<8)
+ DISPLAYLEVEL(3, ", zstd legacy v0.%d+", ZSTD_LEGACY_SUPPORT);
+#endif
+#ifdef ZSTD_GZCOMPRESS
+ DISPLAYLEVEL(3, ", gzip");
+#endif
+#ifdef ZSTD_LZ4COMPRESS
+ DISPLAYLEVEL(3, ", lz4");
+#endif
+#ifdef ZSTD_LZMACOMPRESS
+ DISPLAYLEVEL(3, ", lzma, xz ");
+#endif
+ DISPLAYLEVEL(3, "\n");
+ /* posix support */
+#ifdef _POSIX_C_SOURCE
+ DISPLAYLEVEL(4, "_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
+#endif
+#ifdef _POSIX_VERSION
+ DISPLAYLEVEL(4, "_POSIX_VERSION defined: %ldL \n", (long) _POSIX_VERSION);
+#endif
+#ifdef PLATFORM_POSIX_VERSION
+ DISPLAYLEVEL(4, "PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
+#endif
+}
typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode;
@@ -492,7 +521,7 @@ int main(int argCount, const char* argv[])
switch(argument[0])
{
/* Display help */
- case 'V': g_displayOut=stdout; DISPLAY(WELCOME_MESSAGE); CLEAN_RETURN(0); /* Version Only */
+ case 'V': g_displayOut=stdout; printVersion(); CLEAN_RETURN(0); /* Version Only */
case 'H':
case 'h': g_displayOut=stdout; CLEAN_RETURN(usage_advanced(programName));
@@ -635,24 +664,18 @@ int main(int argCount, const char* argv[])
filenameTable[filenameIdx++] = argument;
}
- if (lastCommand) { DISPLAY("error : command must be followed by argument \n"); CLEAN_RETURN(1); } /* forgotten argument */
+ if (lastCommand) { /* forgotten argument */
+ DISPLAY("error : command must be followed by argument \n");
+ CLEAN_RETURN(1);
+ }
/* Welcome message (if verbose) */
DISPLAYLEVEL(3, WELCOME_MESSAGE);
-#ifdef _POSIX_C_SOURCE
- DISPLAYLEVEL(4, "_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
-#endif
-#ifdef _POSIX_VERSION
- DISPLAYLEVEL(4, "_POSIX_VERSION defined: %ldL\n", (long) _POSIX_VERSION);
-#endif
-#ifdef PLATFORM_POSIX_VERSION
- DISPLAYLEVEL(4, "PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
-#endif
if (nbThreads == 0) {
/* try to guess */
nbThreads = UTIL_countPhysicalCores();
- DISPLAYLEVEL(3, "Note: %d physical core(s) detected\n", nbThreads);
+ DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbThreads);
}
g_utilDisplayLevel = g_displayLevel;
@@ -679,10 +702,17 @@ int main(int argCount, const char* argv[])
}
}
#endif
+
if (operation == zom_list) {
+#ifndef ZSTD_NODECOMPRESS
int const ret = FIO_listMultipleFiles(filenameIdx, filenameTable, g_displayLevel);
CLEAN_RETURN(ret);
+#else
+ DISPLAY("file information is not supported \n");
+ CLEAN_RETURN(1);
+#endif
}
+
/* Check if benchmark is selected */
if (operation==zom_bench) {
#ifndef ZSTD_NOBENCH
@@ -692,7 +722,7 @@ int main(int argCount, const char* argv[])
BMK_setNbSeconds(bench_nbSeconds);
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, &compressionParams, setRealTimePrio);
#endif
- (void)bench_nbSeconds;
+ (void)bench_nbSeconds; (void)blockSize; (void)setRealTimePrio;
goto _end;
}
@@ -719,6 +749,10 @@ int main(int argCount, const char* argv[])
goto _end;
}
+#ifndef ZSTD_NODECOMPRESS
+ if (operation==zom_test) { outFileName=nulmark; FIO_setRemoveSrcFile(0); } /* test mode */
+#endif
+
/* No input filename ==> use stdin and stdout */
filenameIdx += !filenameIdx; /* filenameTable[0] is stdin by default */
if (!strcmp(filenameTable[0], stdinmark) && !outFileName) outFileName = stdoutmark; /* when input is stdin, default output is stdout */
@@ -759,11 +793,11 @@ int main(int argCount, const char* argv[])
else
operationResult = FIO_compressMultipleFilenames(filenameTable, filenameIdx, outFileName ? outFileName : suffix, dictFileName, cLevel, &compressionParams);
#else
+ (void)suffix;
DISPLAY("Compression not supported\n");
#endif
} else { /* decompression or test */
#ifndef ZSTD_NODECOMPRESS
- if (operation==zom_test) { outFileName=nulmark; FIO_setRemoveSrcFile(0); } /* test mode */
FIO_setMemLimit(memLimit);
if (filenameIdx==1 && outFileName)
operationResult = FIO_decompressFilename(outFileName, filenameTable[0], dictFileName);