1902c8ce7SBaptiste Daroussin /*
2b3392d84SAllan Jude * Copyright (c) Yann Collet, Facebook, Inc.
3a19eddc3SBaptiste Daroussin * All rights reserved.
4a19eddc3SBaptiste Daroussin *
5902c8ce7SBaptiste Daroussin * This source code is licensed under both the BSD-style license (found in the
6902c8ce7SBaptiste Daroussin * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7902c8ce7SBaptiste Daroussin * in the COPYING file in the root directory of this source tree).
8653667f9SBaptiste Daroussin * You may select, at your option, one of the above-listed licenses.
9a19eddc3SBaptiste Daroussin */
10a19eddc3SBaptiste Daroussin
11a19eddc3SBaptiste Daroussin
12a19eddc3SBaptiste Daroussin /*-************************************
13a19eddc3SBaptiste Daroussin * Tuning parameters
14a19eddc3SBaptiste Daroussin **************************************/
15a19eddc3SBaptiste Daroussin #ifndef ZSTDCLI_CLEVEL_DEFAULT
16a19eddc3SBaptiste Daroussin # define ZSTDCLI_CLEVEL_DEFAULT 3
17a19eddc3SBaptiste Daroussin #endif
18a19eddc3SBaptiste Daroussin
19a19eddc3SBaptiste Daroussin #ifndef ZSTDCLI_CLEVEL_MAX
20902c8ce7SBaptiste Daroussin # define ZSTDCLI_CLEVEL_MAX 19 /* without using --ultra */
21a19eddc3SBaptiste Daroussin #endif
22a19eddc3SBaptiste Daroussin
23f6ae9767SConrad Meyer #ifndef ZSTDCLI_NBTHREADS_DEFAULT
24f6ae9767SConrad Meyer # define ZSTDCLI_NBTHREADS_DEFAULT 1
25f6ae9767SConrad Meyer #endif
26a19eddc3SBaptiste Daroussin
27a19eddc3SBaptiste Daroussin /*-************************************
28a19eddc3SBaptiste Daroussin * Dependencies
29a19eddc3SBaptiste Daroussin **************************************/
30a19eddc3SBaptiste Daroussin #include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */
31a19eddc3SBaptiste Daroussin #include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
32af73257bSConrad Meyer #include <stdlib.h> /* getenv */
33a19eddc3SBaptiste Daroussin #include <string.h> /* strcmp, strlen */
34bc64b5ceSConrad Meyer #include <stdio.h> /* fprintf(), stdin, stdout, stderr */
35a19eddc3SBaptiste Daroussin #include <errno.h> /* errno */
36bc64b5ceSConrad Meyer #include <assert.h> /* assert */
37bc64b5ceSConrad Meyer
38902c8ce7SBaptiste Daroussin #include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */
39a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
40af73257bSConrad Meyer # include "benchzstd.h" /* BMK_benchFiles */
41a19eddc3SBaptiste Daroussin #endif
42a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
43902c8ce7SBaptiste Daroussin # include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */
44a19eddc3SBaptiste Daroussin #endif
45b3392d84SAllan Jude #ifndef ZSTD_NOTRACE
46b3392d84SAllan Jude # include "zstdcli_trace.h"
47b3392d84SAllan Jude #endif
48bc64b5ceSConrad Meyer #include "../lib/zstd.h" /* ZSTD_VERSION_STRING, ZSTD_minCLevel, ZSTD_maxCLevel */
49a19eddc3SBaptiste Daroussin
50a19eddc3SBaptiste Daroussin
51a19eddc3SBaptiste Daroussin /*-************************************
52a19eddc3SBaptiste Daroussin * Constants
53a19eddc3SBaptiste Daroussin **************************************/
54a19eddc3SBaptiste Daroussin #define COMPRESSOR_NAME "zstd command line interface"
55a19eddc3SBaptiste Daroussin #ifndef ZSTD_VERSION
56a19eddc3SBaptiste Daroussin # define ZSTD_VERSION "v" ZSTD_VERSION_STRING
57a19eddc3SBaptiste Daroussin #endif
58a19eddc3SBaptiste Daroussin #define AUTHOR "Yann Collet"
59a19eddc3SBaptiste Daroussin #define WELCOME_MESSAGE "*** %s %i-bits %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR
60a19eddc3SBaptiste Daroussin
61ffcbc2d7SBaptiste Daroussin #define ZSTD_ZSTDMT "zstdmt"
62a19eddc3SBaptiste Daroussin #define ZSTD_UNZSTD "unzstd"
63a19eddc3SBaptiste Daroussin #define ZSTD_CAT "zstdcat"
6442239e68SConrad Meyer #define ZSTD_ZCAT "zcat"
65a19eddc3SBaptiste Daroussin #define ZSTD_GZ "gzip"
66a19eddc3SBaptiste Daroussin #define ZSTD_GUNZIP "gunzip"
67a19eddc3SBaptiste Daroussin #define ZSTD_GZCAT "gzcat"
68a19eddc3SBaptiste Daroussin #define ZSTD_LZMA "lzma"
69affe9eafSBaptiste Daroussin #define ZSTD_UNLZMA "unlzma"
70a19eddc3SBaptiste Daroussin #define ZSTD_XZ "xz"
71affe9eafSBaptiste Daroussin #define ZSTD_UNXZ "unxz"
72653667f9SBaptiste Daroussin #define ZSTD_LZ4 "lz4"
73653667f9SBaptiste Daroussin #define ZSTD_UNLZ4 "unlz4"
74a19eddc3SBaptiste Daroussin
75a19eddc3SBaptiste Daroussin #define KB *(1 <<10)
76a19eddc3SBaptiste Daroussin #define MB *(1 <<20)
77a19eddc3SBaptiste Daroussin #define GB *(1U<<30)
78a19eddc3SBaptiste Daroussin
79902c8ce7SBaptiste Daroussin #define DISPLAY_LEVEL_DEFAULT 2
80a19eddc3SBaptiste Daroussin
81a19eddc3SBaptiste Daroussin static const char* g_defaultDictName = "dictionary";
82a19eddc3SBaptiste Daroussin static const unsigned g_defaultMaxDictSize = 110 KB;
83a19eddc3SBaptiste Daroussin static const int g_defaultDictCLevel = 3;
84a19eddc3SBaptiste Daroussin static const unsigned g_defaultSelectivityLevel = 9;
85653667f9SBaptiste Daroussin static const unsigned g_defaultMaxWindowLog = 27;
86a19eddc3SBaptiste Daroussin #define OVERLAP_LOG_DEFAULT 9999
87653667f9SBaptiste Daroussin #define LDM_PARAM_DEFAULT 9999 /* Default for parameters where 0 is valid */
88a19eddc3SBaptiste Daroussin static U32 g_overlapLog = OVERLAP_LOG_DEFAULT;
89653667f9SBaptiste Daroussin static U32 g_ldmHashLog = 0;
90653667f9SBaptiste Daroussin static U32 g_ldmMinMatch = 0;
91af73257bSConrad Meyer static U32 g_ldmHashRateLog = LDM_PARAM_DEFAULT;
92653667f9SBaptiste Daroussin static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT;
93a19eddc3SBaptiste Daroussin
94a19eddc3SBaptiste Daroussin
95706cfae4SConrad Meyer #define DEFAULT_ACCEL 1
96706cfae4SConrad Meyer
97706cfae4SConrad Meyer typedef enum { cover, fastCover, legacy } dictType;
98706cfae4SConrad Meyer
99a19eddc3SBaptiste Daroussin /*-************************************
100a19eddc3SBaptiste Daroussin * Display Macros
101a19eddc3SBaptiste Daroussin **************************************/
102bc64b5ceSConrad Meyer #define DISPLAY_F(f, ...) fprintf((f), __VA_ARGS__)
103bc64b5ceSConrad Meyer #define DISPLAYOUT(...) DISPLAY_F(stdout, __VA_ARGS__)
104bc64b5ceSConrad Meyer #define DISPLAY(...) DISPLAY_F(stderr, __VA_ARGS__)
105ffcbc2d7SBaptiste Daroussin #define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
106902c8ce7SBaptiste Daroussin static int g_displayLevel = DISPLAY_LEVEL_DEFAULT; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
107a19eddc3SBaptiste Daroussin
108a19eddc3SBaptiste Daroussin
109a19eddc3SBaptiste Daroussin /*-************************************
110b3392d84SAllan Jude * Check Version (when CLI linked to dynamic library)
111b3392d84SAllan Jude **************************************/
112b3392d84SAllan Jude
113b3392d84SAllan Jude /* Due to usage of experimental symbols and capabilities by the CLI,
114b3392d84SAllan Jude * the CLI must be linked against a dynamic library of same version */
checkLibVersion(void)115b3392d84SAllan Jude static void checkLibVersion(void)
116b3392d84SAllan Jude {
117b3392d84SAllan Jude if (strcmp(ZSTD_VERSION_STRING, ZSTD_versionString())) {
118b3392d84SAllan Jude DISPLAYLEVEL(1, "Error : incorrect library version (expecting : %s ; actual : %s ) \n",
119b3392d84SAllan Jude ZSTD_VERSION_STRING, ZSTD_versionString());
120b3392d84SAllan Jude DISPLAYLEVEL(1, "Please update library to version %s, or use stand-alone zstd binary \n",
121b3392d84SAllan Jude ZSTD_VERSION_STRING);
122b3392d84SAllan Jude exit(1);
123b3392d84SAllan Jude }
124b3392d84SAllan Jude }
125b3392d84SAllan Jude
126b3392d84SAllan Jude
127b3392d84SAllan Jude /*-************************************
128a19eddc3SBaptiste Daroussin * Command Line
129a19eddc3SBaptiste Daroussin **************************************/
130bc64b5ceSConrad Meyer /* print help either in `stderr` or `stdout` depending on originating request
131bc64b5ceSConrad Meyer * error (badusage) => stderr
132bc64b5ceSConrad Meyer * help (usage_advanced) => stdout
133bc64b5ceSConrad Meyer */
usage(FILE * f,const char * programName)134bc64b5ceSConrad Meyer static void usage(FILE* f, const char* programName)
135a19eddc3SBaptiste Daroussin {
136bc64b5ceSConrad Meyer DISPLAY_F(f, "Usage : \n");
137bc64b5ceSConrad Meyer DISPLAY_F(f, " %s [args] [FILE(s)] [-o file] \n", programName);
138bc64b5ceSConrad Meyer DISPLAY_F(f, "\n");
139bc64b5ceSConrad Meyer DISPLAY_F(f, "FILE : a filename \n");
140bc64b5ceSConrad Meyer DISPLAY_F(f, " with no FILE, or when FILE is - , read standard input\n");
141bc64b5ceSConrad Meyer DISPLAY_F(f, "Arguments : \n");
142a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOCOMPRESS
143bc64b5ceSConrad Meyer DISPLAY_F(f, " -# : # compression level (1-%d, default: %d) \n", ZSTDCLI_CLEVEL_MAX, ZSTDCLI_CLEVEL_DEFAULT);
144a19eddc3SBaptiste Daroussin #endif
145a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODECOMPRESS
146bc64b5ceSConrad Meyer DISPLAY_F(f, " -d : decompression \n");
147a19eddc3SBaptiste Daroussin #endif
148bc64b5ceSConrad Meyer DISPLAY_F(f, " -D DICT: use DICT as Dictionary for compression or decompression \n");
149bc64b5ceSConrad Meyer DISPLAY_F(f, " -o file: result stored into `file` (only 1 output file) \n");
150b3392d84SAllan Jude DISPLAY_F(f, " -f : disable input and output checks. Allows overwriting existing files,\n");
151b3392d84SAllan Jude DISPLAY_F(f, " input from console, output to stdout, operating on links,\n");
152b3392d84SAllan Jude DISPLAY_F(f, " block devices, etc.\n");
153bc64b5ceSConrad Meyer DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \n");
154bc64b5ceSConrad Meyer DISPLAY_F(f, " -k : preserve source file(s) (default) \n");
155bc64b5ceSConrad Meyer DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
156a19eddc3SBaptiste Daroussin }
157a19eddc3SBaptiste Daroussin
usage_advanced(const char * programName)158bc64b5ceSConrad Meyer static void usage_advanced(const char* programName)
159a19eddc3SBaptiste Daroussin {
160bc64b5ceSConrad Meyer DISPLAYOUT(WELCOME_MESSAGE);
161bc64b5ceSConrad Meyer usage(stdout, programName);
162bc64b5ceSConrad Meyer DISPLAYOUT( "\n");
163bc64b5ceSConrad Meyer DISPLAYOUT( "Advanced arguments : \n");
164bc64b5ceSConrad Meyer DISPLAYOUT( " -V : display Version number and exit \n");
165bc64b5ceSConrad Meyer
166b3392d84SAllan Jude DISPLAYOUT( " -c : write to standard output (even if it is the console) \n");
167bc64b5ceSConrad Meyer
168bc64b5ceSConrad Meyer DISPLAYOUT( " -v : verbose mode; specify multiple times to increase verbosity \n");
169bc64b5ceSConrad Meyer DISPLAYOUT( " -q : suppress warnings; specify twice to suppress errors too \n");
170b3392d84SAllan Jude DISPLAYOUT( "--[no-]progress : forcibly display, or never display the progress counter.\n");
171b3392d84SAllan Jude DISPLAYOUT( " note: any (de)compressed output to terminal will mix with progress counter text. \n");
172bc64b5ceSConrad Meyer
173ffcbc2d7SBaptiste Daroussin #ifdef UTIL_HAS_CREATEFILELIST
174bc64b5ceSConrad Meyer DISPLAYOUT( " -r : operate recursively on directories \n");
175f6ae9767SConrad Meyer DISPLAYOUT( "--filelist FILE : read list of files to operate upon from FILE \n");
176f6ae9767SConrad Meyer DISPLAYOUT( "--output-dir-flat DIR : processed files are stored into DIR \n");
177a19eddc3SBaptiste Daroussin #endif
178bc64b5ceSConrad Meyer
179f6ae9767SConrad Meyer #ifdef UTIL_HAS_MIRRORFILELIST
180f6ae9767SConrad Meyer DISPLAYOUT( "--output-dir-mirror DIR : processed files are stored into DIR respecting original directory structure \n");
181f6ae9767SConrad Meyer #endif
182f6ae9767SConrad Meyer
183f6ae9767SConrad Meyer
184f6ae9767SConrad Meyer #ifndef ZSTD_NOCOMPRESS
185f6ae9767SConrad Meyer DISPLAYOUT( "--[no-]check : during compression, add XXH64 integrity checksum to frame (default: enabled)");
186f6ae9767SConrad Meyer #ifndef ZSTD_NODECOMPRESS
187f6ae9767SConrad Meyer DISPLAYOUT( ". If specified with -d, decompressor will ignore/validate checksums in compressed frame (default: validate).");
188f6ae9767SConrad Meyer #endif
189f6ae9767SConrad Meyer #else
190f6ae9767SConrad Meyer #ifdef ZSTD_NOCOMPRESS
191f6ae9767SConrad Meyer DISPLAYOUT( "--[no-]check : during decompression, ignore/validate checksums in compressed frame (default: validate).");
192f6ae9767SConrad Meyer #endif
193f6ae9767SConrad Meyer #endif /* ZSTD_NOCOMPRESS */
194b3392d84SAllan Jude
195b3392d84SAllan Jude #ifndef ZSTD_NOTRACE
196b3392d84SAllan Jude DISPLAYOUT( "\n");
197b3392d84SAllan Jude DISPLAYOUT( "--trace FILE : log tracing information to FILE.");
198b3392d84SAllan Jude #endif
199f6ae9767SConrad Meyer DISPLAYOUT( "\n");
200f6ae9767SConrad Meyer
201bc64b5ceSConrad Meyer DISPLAYOUT( "-- : All arguments after \"--\" are treated as files \n");
202bc64b5ceSConrad Meyer
203bc64b5ceSConrad Meyer #ifndef ZSTD_NOCOMPRESS
204bc64b5ceSConrad Meyer DISPLAYOUT( "\n");
205bc64b5ceSConrad Meyer DISPLAYOUT( "Advanced compression arguments : \n");
206bc64b5ceSConrad Meyer DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
207bc64b5ceSConrad Meyer DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog);
208bc64b5ceSConrad Meyer DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1);
209bc64b5ceSConrad Meyer DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n");
210b3392d84SAllan Jude DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n");
211b3392d84SAllan Jude DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n");
212bc64b5ceSConrad Meyer # ifdef ZSTD_MULTITHREAD
213bc64b5ceSConrad Meyer DISPLAYOUT( " -T# : spawns # compression threads (default: 1, 0==# cores) \n");
214bc64b5ceSConrad Meyer DISPLAYOUT( " -B# : select size of each job (default: 0==automatic) \n");
215bc64b5ceSConrad Meyer DISPLAYOUT( "--single-thread : use a single thread for both I/O and compression (result slightly different than -T1) \n");
216b3392d84SAllan Jude DISPLAYOUT( "--auto-threads={physical,logical} (default: physical} : use either physical cores or logical cores as default when specifying -T0 \n");
217bc64b5ceSConrad Meyer DISPLAYOUT( "--rsyncable : compress using a rsync-friendly method (-B sets block size) \n");
218bc64b5ceSConrad Meyer # endif
219bc64b5ceSConrad Meyer DISPLAYOUT( "--exclude-compressed: only compress files that are not already compressed \n");
220bc64b5ceSConrad Meyer DISPLAYOUT( "--stream-size=# : specify size of streaming input from `stdin` \n");
221bc64b5ceSConrad Meyer DISPLAYOUT( "--size-hint=# optimize compression parameters for streaming input of approximately this size \n");
222bc64b5ceSConrad Meyer DISPLAYOUT( "--target-compressed-block-size=# : generate compressed block of approximately targeted size \n");
223bc64b5ceSConrad Meyer DISPLAYOUT( "--no-dictID : don't write dictID into header (dictionary compression only) \n");
224bc64b5ceSConrad Meyer DISPLAYOUT( "--[no-]compress-literals : force (un)compressed literals \n");
225bc64b5ceSConrad Meyer
226bc64b5ceSConrad Meyer DISPLAYOUT( "--format=zstd : compress files to the .zst format (default) \n");
227a19eddc3SBaptiste Daroussin #ifdef ZSTD_GZCOMPRESS
228bc64b5ceSConrad Meyer DISPLAYOUT( "--format=gzip : compress files to the .gz format \n");
229a19eddc3SBaptiste Daroussin #endif
230a19eddc3SBaptiste Daroussin #ifdef ZSTD_LZMACOMPRESS
231bc64b5ceSConrad Meyer DISPLAYOUT( "--format=xz : compress files to the .xz format \n");
232bc64b5ceSConrad Meyer DISPLAYOUT( "--format=lzma : compress files to the .lzma format \n");
233a19eddc3SBaptiste Daroussin #endif
234ffcbc2d7SBaptiste Daroussin #ifdef ZSTD_LZ4COMPRESS
235bc64b5ceSConrad Meyer DISPLAYOUT( "--format=lz4 : compress files to the .lz4 format \n");
236a19eddc3SBaptiste Daroussin #endif
237bc64b5ceSConrad Meyer #endif /* !ZSTD_NOCOMPRESS */
238bc64b5ceSConrad Meyer
239a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODECOMPRESS
240bc64b5ceSConrad Meyer DISPLAYOUT( "\n");
241bc64b5ceSConrad Meyer DISPLAYOUT( "Advanced decompression arguments : \n");
242bc64b5ceSConrad Meyer DISPLAYOUT( " -l : print information about zstd compressed files \n");
243bc64b5ceSConrad Meyer DISPLAYOUT( "--test : test compressed file integrity \n");
244bc64b5ceSConrad Meyer DISPLAYOUT( " -M# : Set a memory usage limit for decompression \n");
245ffcbc2d7SBaptiste Daroussin # if ZSTD_SPARSE_DEFAULT
246bc64b5ceSConrad Meyer DISPLAYOUT( "--[no-]sparse : sparse mode (default: enabled on file, disabled on stdout) \n");
247ffcbc2d7SBaptiste Daroussin # else
248bc64b5ceSConrad Meyer DISPLAYOUT( "--[no-]sparse : sparse mode (default: disabled) \n");
249ffcbc2d7SBaptiste Daroussin # endif
250bc64b5ceSConrad Meyer #endif /* ZSTD_NODECOMPRESS */
251bc64b5ceSConrad Meyer
252a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
253bc64b5ceSConrad Meyer DISPLAYOUT( "\n");
254bc64b5ceSConrad Meyer DISPLAYOUT( "Dictionary builder : \n");
255bc64b5ceSConrad Meyer DISPLAYOUT( "--train ## : create a dictionary from a training set of files \n");
256bc64b5ceSConrad Meyer DISPLAYOUT( "--train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]] : use the cover algorithm with optional args \n");
257bc64b5ceSConrad Meyer DISPLAYOUT( "--train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]] : use the fast cover algorithm with optional args \n");
258bc64b5ceSConrad Meyer DISPLAYOUT( "--train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u) \n", g_defaultSelectivityLevel);
259bc64b5ceSConrad Meyer DISPLAYOUT( " -o DICT : DICT is dictionary name (default: %s) \n", g_defaultDictName);
260bc64b5ceSConrad Meyer DISPLAYOUT( "--maxdict=# : limit dictionary to specified size (default: %u) \n", g_defaultMaxDictSize);
261bc64b5ceSConrad Meyer DISPLAYOUT( "--dictID=# : force dictionary ID to specified value (default: random) \n");
262a19eddc3SBaptiste Daroussin #endif
263bc64b5ceSConrad Meyer
264a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
265bc64b5ceSConrad Meyer DISPLAYOUT( "\n");
266bc64b5ceSConrad Meyer DISPLAYOUT( "Benchmark arguments : \n");
267bc64b5ceSConrad Meyer DISPLAYOUT( " -b# : benchmark file(s), using # compression level (default: %d) \n", ZSTDCLI_CLEVEL_DEFAULT);
268bc64b5ceSConrad Meyer DISPLAYOUT( " -e# : test all compression levels successively from -b# to -e# (default: 1) \n");
269bc64b5ceSConrad Meyer DISPLAYOUT( " -i# : minimum evaluation time in seconds (default: 3s) \n");
270bc64b5ceSConrad Meyer DISPLAYOUT( " -B# : cut file into independent blocks of size # (default: no block) \n");
271bc64b5ceSConrad Meyer DISPLAYOUT( " -S : output one benchmark result per input file (default: consolidated result) \n");
272bc64b5ceSConrad Meyer DISPLAYOUT( "--priority=rt : set process priority to real-time \n");
273a19eddc3SBaptiste Daroussin #endif
274bc64b5ceSConrad Meyer
275a19eddc3SBaptiste Daroussin }
276a19eddc3SBaptiste Daroussin
badusage(const char * programName)277bc64b5ceSConrad Meyer static void badusage(const char* programName)
278a19eddc3SBaptiste Daroussin {
279a19eddc3SBaptiste Daroussin DISPLAYLEVEL(1, "Incorrect parameters \n");
280bc64b5ceSConrad Meyer if (g_displayLevel >= 2) usage(stderr, programName);
281a19eddc3SBaptiste Daroussin }
282a19eddc3SBaptiste Daroussin
waitEnter(void)283a19eddc3SBaptiste Daroussin static void waitEnter(void)
284a19eddc3SBaptiste Daroussin {
285a19eddc3SBaptiste Daroussin int unused;
286a19eddc3SBaptiste Daroussin DISPLAY("Press enter to continue... \n");
287a19eddc3SBaptiste Daroussin unused = getchar();
288a19eddc3SBaptiste Daroussin (void)unused;
289a19eddc3SBaptiste Daroussin }
290a19eddc3SBaptiste Daroussin
lastNameFromPath(const char * path)291ffcbc2d7SBaptiste Daroussin static const char* lastNameFromPath(const char* path)
292ffcbc2d7SBaptiste Daroussin {
293ffcbc2d7SBaptiste Daroussin const char* name = path;
294ffcbc2d7SBaptiste Daroussin if (strrchr(name, '/')) name = strrchr(name, '/') + 1;
295ffcbc2d7SBaptiste Daroussin if (strrchr(name, '\\')) name = strrchr(name, '\\') + 1; /* windows */
296ffcbc2d7SBaptiste Daroussin return name;
297ffcbc2d7SBaptiste Daroussin }
298ffcbc2d7SBaptiste Daroussin
299ffcbc2d7SBaptiste Daroussin /*! exeNameMatch() :
300ffcbc2d7SBaptiste Daroussin @return : a non-zero value if exeName matches test, excluding the extension
301ffcbc2d7SBaptiste Daroussin */
exeNameMatch(const char * exeName,const char * test)302ffcbc2d7SBaptiste Daroussin static int exeNameMatch(const char* exeName, const char* test)
303ffcbc2d7SBaptiste Daroussin {
304ffcbc2d7SBaptiste Daroussin return !strncmp(exeName, test, strlen(test)) &&
305ffcbc2d7SBaptiste Daroussin (exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.');
306ffcbc2d7SBaptiste Daroussin }
307ffcbc2d7SBaptiste Daroussin
errorOut(const char * msg)308706cfae4SConrad Meyer static void errorOut(const char* msg)
309706cfae4SConrad Meyer {
310706cfae4SConrad Meyer DISPLAY("%s \n", msg); exit(1);
311706cfae4SConrad Meyer }
312706cfae4SConrad Meyer
313af73257bSConrad Meyer /*! readU32FromCharChecked() :
314af73257bSConrad Meyer * @return 0 if success, and store the result in *value.
31542239e68SConrad Meyer * allows and interprets K, KB, KiB, M, MB and MiB suffix.
31642239e68SConrad Meyer * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
317af73257bSConrad Meyer * @return 1 if an overflow error occurs */
readU32FromCharChecked(const char ** stringPtr,unsigned * value)318af73257bSConrad Meyer static int readU32FromCharChecked(const char** stringPtr, unsigned* value)
319a19eddc3SBaptiste Daroussin {
320a19eddc3SBaptiste Daroussin unsigned result = 0;
321706cfae4SConrad Meyer while ((**stringPtr >='0') && (**stringPtr <='9')) {
322bc64b5ceSConrad Meyer unsigned const max = ((unsigned)(-1)) / 10;
323bc64b5ceSConrad Meyer unsigned last = result;
3243f774a5eSConrad Meyer if (result > max) return 1; /* overflow error */
3253f774a5eSConrad Meyer result *= 10;
3263f774a5eSConrad Meyer result += (unsigned)(**stringPtr - '0');
327bc64b5ceSConrad Meyer if (result < last) return 1; /* overflow error */
3283f774a5eSConrad Meyer (*stringPtr)++ ;
329706cfae4SConrad Meyer }
330a19eddc3SBaptiste Daroussin if ((**stringPtr=='K') || (**stringPtr=='M')) {
331706cfae4SConrad Meyer unsigned const maxK = ((unsigned)(-1)) >> 10;
3323f774a5eSConrad Meyer if (result > maxK) return 1; /* overflow error */
333a19eddc3SBaptiste Daroussin result <<= 10;
334706cfae4SConrad Meyer if (**stringPtr=='M') {
3353f774a5eSConrad Meyer if (result > maxK) return 1; /* overflow error */
336706cfae4SConrad Meyer result <<= 10;
337706cfae4SConrad Meyer }
338706cfae4SConrad Meyer (*stringPtr)++; /* skip `K` or `M` */
339a19eddc3SBaptiste Daroussin if (**stringPtr=='i') (*stringPtr)++;
340a19eddc3SBaptiste Daroussin if (**stringPtr=='B') (*stringPtr)++;
341a19eddc3SBaptiste Daroussin }
342af73257bSConrad Meyer *value = result;
343af73257bSConrad Meyer return 0;
344af73257bSConrad Meyer }
345af73257bSConrad Meyer
346af73257bSConrad Meyer /*! readU32FromChar() :
347af73257bSConrad Meyer * @return : unsigned integer value read from input in `char` format.
348af73257bSConrad Meyer * allows and interprets K, KB, KiB, M, MB and MiB suffix.
349af73257bSConrad Meyer * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
350af73257bSConrad Meyer * Note : function will exit() program if digit sequence overflows */
readU32FromChar(const char ** stringPtr)351af73257bSConrad Meyer static unsigned readU32FromChar(const char** stringPtr) {
352bc64b5ceSConrad Meyer static const char errorMsg[] = "error: numeric value overflows 32-bit unsigned int";
353af73257bSConrad Meyer unsigned result;
354af73257bSConrad Meyer if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); }
355a19eddc3SBaptiste Daroussin return result;
356a19eddc3SBaptiste Daroussin }
357a19eddc3SBaptiste Daroussin
358b3392d84SAllan Jude /*! readIntFromChar() :
359b3392d84SAllan Jude * @return : signed integer value read from input in `char` format.
360b3392d84SAllan Jude * allows and interprets K, KB, KiB, M, MB and MiB suffix.
361b3392d84SAllan Jude * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
362b3392d84SAllan Jude * Note : function will exit() program if digit sequence overflows */
readIntFromChar(const char ** stringPtr)363b3392d84SAllan Jude static int readIntFromChar(const char** stringPtr) {
364b3392d84SAllan Jude static const char errorMsg[] = "error: numeric value overflows 32-bit int";
365b3392d84SAllan Jude int sign = 1;
366b3392d84SAllan Jude unsigned result;
367b3392d84SAllan Jude if (**stringPtr=='-') {
368b3392d84SAllan Jude (*stringPtr)++;
369b3392d84SAllan Jude sign = -1;
370b3392d84SAllan Jude }
371b3392d84SAllan Jude if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); }
372b3392d84SAllan Jude return (int) result * sign;
373b3392d84SAllan Jude }
374b3392d84SAllan Jude
375bc64b5ceSConrad Meyer /*! readSizeTFromCharChecked() :
376bc64b5ceSConrad Meyer * @return 0 if success, and store the result in *value.
377bc64b5ceSConrad Meyer * allows and interprets K, KB, KiB, M, MB and MiB suffix.
378bc64b5ceSConrad Meyer * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
379bc64b5ceSConrad Meyer * @return 1 if an overflow error occurs */
readSizeTFromCharChecked(const char ** stringPtr,size_t * value)380bc64b5ceSConrad Meyer static int readSizeTFromCharChecked(const char** stringPtr, size_t* value)
381bc64b5ceSConrad Meyer {
382bc64b5ceSConrad Meyer size_t result = 0;
383bc64b5ceSConrad Meyer while ((**stringPtr >='0') && (**stringPtr <='9')) {
384bc64b5ceSConrad Meyer size_t const max = ((size_t)(-1)) / 10;
385bc64b5ceSConrad Meyer size_t last = result;
386bc64b5ceSConrad Meyer if (result > max) return 1; /* overflow error */
387bc64b5ceSConrad Meyer result *= 10;
388bc64b5ceSConrad Meyer result += (size_t)(**stringPtr - '0');
389bc64b5ceSConrad Meyer if (result < last) return 1; /* overflow error */
390bc64b5ceSConrad Meyer (*stringPtr)++ ;
391bc64b5ceSConrad Meyer }
392bc64b5ceSConrad Meyer if ((**stringPtr=='K') || (**stringPtr=='M')) {
393bc64b5ceSConrad Meyer size_t const maxK = ((size_t)(-1)) >> 10;
394bc64b5ceSConrad Meyer if (result > maxK) return 1; /* overflow error */
395bc64b5ceSConrad Meyer result <<= 10;
396bc64b5ceSConrad Meyer if (**stringPtr=='M') {
397bc64b5ceSConrad Meyer if (result > maxK) return 1; /* overflow error */
398bc64b5ceSConrad Meyer result <<= 10;
399bc64b5ceSConrad Meyer }
400bc64b5ceSConrad Meyer (*stringPtr)++; /* skip `K` or `M` */
401bc64b5ceSConrad Meyer if (**stringPtr=='i') (*stringPtr)++;
402bc64b5ceSConrad Meyer if (**stringPtr=='B') (*stringPtr)++;
403bc64b5ceSConrad Meyer }
404bc64b5ceSConrad Meyer *value = result;
405bc64b5ceSConrad Meyer return 0;
406bc64b5ceSConrad Meyer }
407bc64b5ceSConrad Meyer
408bc64b5ceSConrad Meyer /*! readSizeTFromChar() :
409bc64b5ceSConrad Meyer * @return : size_t value read from input in `char` format.
410bc64b5ceSConrad Meyer * allows and interprets K, KB, KiB, M, MB and MiB suffix.
411bc64b5ceSConrad Meyer * Will also modify `*stringPtr`, advancing it to position where it stopped reading.
412bc64b5ceSConrad Meyer * Note : function will exit() program if digit sequence overflows */
readSizeTFromChar(const char ** stringPtr)413bc64b5ceSConrad Meyer static size_t readSizeTFromChar(const char** stringPtr) {
414bc64b5ceSConrad Meyer static const char errorMsg[] = "error: numeric value overflows size_t";
415bc64b5ceSConrad Meyer size_t result;
416bc64b5ceSConrad Meyer if (readSizeTFromCharChecked(stringPtr, &result)) { errorOut(errorMsg); }
417bc64b5ceSConrad Meyer return result;
418bc64b5ceSConrad Meyer }
419bc64b5ceSConrad Meyer
420a19eddc3SBaptiste Daroussin /** longCommandWArg() :
421a19eddc3SBaptiste Daroussin * check if *stringPtr is the same as longCommand.
422a19eddc3SBaptiste Daroussin * If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand.
423a19eddc3SBaptiste Daroussin * @return 0 and doesn't modify *stringPtr otherwise.
424a19eddc3SBaptiste Daroussin */
longCommandWArg(const char ** stringPtr,const char * longCommand)425ea684039SConrad Meyer static int longCommandWArg(const char** stringPtr, const char* longCommand)
426a19eddc3SBaptiste Daroussin {
427a19eddc3SBaptiste Daroussin size_t const comSize = strlen(longCommand);
428a19eddc3SBaptiste Daroussin int const result = !strncmp(*stringPtr, longCommand, comSize);
429a19eddc3SBaptiste Daroussin if (result) *stringPtr += comSize;
430a19eddc3SBaptiste Daroussin return result;
431a19eddc3SBaptiste Daroussin }
432a19eddc3SBaptiste Daroussin
433a19eddc3SBaptiste Daroussin
434a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
43590f4bdbeSConrad Meyer
43690f4bdbeSConrad Meyer static const unsigned kDefaultRegression = 1;
437a19eddc3SBaptiste Daroussin /**
438a19eddc3SBaptiste Daroussin * parseCoverParameters() :
439ffcbc2d7SBaptiste Daroussin * reads cover parameters from *stringPtr (e.g. "--train-cover=k=48,d=8,steps=32") into *params
440a19eddc3SBaptiste Daroussin * @return 1 means that cover parameters were correct
441a19eddc3SBaptiste Daroussin * @return 0 in case of malformed parameters
442a19eddc3SBaptiste Daroussin */
parseCoverParameters(const char * stringPtr,ZDICT_cover_params_t * params)443affe9eafSBaptiste Daroussin static unsigned parseCoverParameters(const char* stringPtr, ZDICT_cover_params_t* params)
444a19eddc3SBaptiste Daroussin {
445a19eddc3SBaptiste Daroussin memset(params, 0, sizeof(*params));
446a19eddc3SBaptiste Daroussin for (; ;) {
447a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "k=")) { params->k = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
448a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "d=")) { params->d = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
449a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "steps=")) { params->steps = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
450706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "split=")) {
451706cfae4SConrad Meyer unsigned splitPercentage = readU32FromChar(&stringPtr);
452706cfae4SConrad Meyer params->splitPoint = (double)splitPercentage / 100.0;
453706cfae4SConrad Meyer if (stringPtr[0]==',') { stringPtr++; continue; } else break;
454706cfae4SConrad Meyer }
455fa94c738SConrad Meyer if (longCommandWArg(&stringPtr, "shrink")) {
456fa94c738SConrad Meyer params->shrinkDictMaxRegression = kDefaultRegression;
457fa94c738SConrad Meyer params->shrinkDict = 1;
458fa94c738SConrad Meyer if (stringPtr[0]=='=') {
459fa94c738SConrad Meyer stringPtr++;
460fa94c738SConrad Meyer params->shrinkDictMaxRegression = readU32FromChar(&stringPtr);
461fa94c738SConrad Meyer }
462fa94c738SConrad Meyer if (stringPtr[0]==',') {
463fa94c738SConrad Meyer stringPtr++;
464fa94c738SConrad Meyer continue;
465fa94c738SConrad Meyer }
466fa94c738SConrad Meyer else break;
467fa94c738SConrad Meyer }
468a19eddc3SBaptiste Daroussin return 0;
469a19eddc3SBaptiste Daroussin }
470a19eddc3SBaptiste Daroussin if (stringPtr[0] != 0) return 0;
471fa94c738SConrad Meyer 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);
472706cfae4SConrad Meyer return 1;
473706cfae4SConrad Meyer }
474706cfae4SConrad Meyer
475706cfae4SConrad Meyer /**
476706cfae4SConrad Meyer * parseFastCoverParameters() :
477706cfae4SConrad Meyer * reads fastcover parameters from *stringPtr (e.g. "--train-fastcover=k=48,d=8,f=20,steps=32,accel=2") into *params
478706cfae4SConrad Meyer * @return 1 means that fastcover parameters were correct
479706cfae4SConrad Meyer * @return 0 in case of malformed parameters
480706cfae4SConrad Meyer */
parseFastCoverParameters(const char * stringPtr,ZDICT_fastCover_params_t * params)481706cfae4SConrad Meyer static unsigned parseFastCoverParameters(const char* stringPtr, ZDICT_fastCover_params_t* params)
482706cfae4SConrad Meyer {
483706cfae4SConrad Meyer memset(params, 0, sizeof(*params));
484706cfae4SConrad Meyer for (; ;) {
485706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "k=")) { params->k = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
486706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "d=")) { params->d = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
487706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "f=")) { params->f = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
488706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "steps=")) { params->steps = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
489706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "accel=")) { params->accel = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
490706cfae4SConrad Meyer if (longCommandWArg(&stringPtr, "split=")) {
491706cfae4SConrad Meyer unsigned splitPercentage = readU32FromChar(&stringPtr);
492706cfae4SConrad Meyer params->splitPoint = (double)splitPercentage / 100.0;
493706cfae4SConrad Meyer if (stringPtr[0]==',') { stringPtr++; continue; } else break;
494706cfae4SConrad Meyer }
495fa94c738SConrad Meyer if (longCommandWArg(&stringPtr, "shrink")) {
496fa94c738SConrad Meyer params->shrinkDictMaxRegression = kDefaultRegression;
497fa94c738SConrad Meyer params->shrinkDict = 1;
498fa94c738SConrad Meyer if (stringPtr[0]=='=') {
499fa94c738SConrad Meyer stringPtr++;
500fa94c738SConrad Meyer params->shrinkDictMaxRegression = readU32FromChar(&stringPtr);
501fa94c738SConrad Meyer }
502fa94c738SConrad Meyer if (stringPtr[0]==',') {
503fa94c738SConrad Meyer stringPtr++;
504fa94c738SConrad Meyer continue;
505fa94c738SConrad Meyer }
506fa94c738SConrad Meyer else break;
507fa94c738SConrad Meyer }
508706cfae4SConrad Meyer return 0;
509706cfae4SConrad Meyer }
510706cfae4SConrad Meyer if (stringPtr[0] != 0) return 0;
511fa94c738SConrad Meyer 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);
512a19eddc3SBaptiste Daroussin return 1;
513a19eddc3SBaptiste Daroussin }
514ffcbc2d7SBaptiste Daroussin
515ffcbc2d7SBaptiste Daroussin /**
516ffcbc2d7SBaptiste Daroussin * parseLegacyParameters() :
5173f774a5eSConrad Meyer * reads legacy dictionary builder parameters from *stringPtr (e.g. "--train-legacy=selectivity=8") into *selectivity
518ffcbc2d7SBaptiste Daroussin * @return 1 means that legacy dictionary builder parameters were correct
519ffcbc2d7SBaptiste Daroussin * @return 0 in case of malformed parameters
520ffcbc2d7SBaptiste Daroussin */
parseLegacyParameters(const char * stringPtr,unsigned * selectivity)521ffcbc2d7SBaptiste Daroussin static unsigned parseLegacyParameters(const char* stringPtr, unsigned* selectivity)
522ffcbc2d7SBaptiste Daroussin {
523ffcbc2d7SBaptiste Daroussin if (!longCommandWArg(&stringPtr, "s=") && !longCommandWArg(&stringPtr, "selectivity=")) { return 0; }
524ffcbc2d7SBaptiste Daroussin *selectivity = readU32FromChar(&stringPtr);
525ffcbc2d7SBaptiste Daroussin if (stringPtr[0] != 0) return 0;
526ffcbc2d7SBaptiste Daroussin DISPLAYLEVEL(4, "legacy: selectivity=%u\n", *selectivity);
527ffcbc2d7SBaptiste Daroussin return 1;
528ffcbc2d7SBaptiste Daroussin }
529ffcbc2d7SBaptiste Daroussin
defaultCoverParams(void)530affe9eafSBaptiste Daroussin static ZDICT_cover_params_t defaultCoverParams(void)
531ffcbc2d7SBaptiste Daroussin {
532affe9eafSBaptiste Daroussin ZDICT_cover_params_t params;
533ffcbc2d7SBaptiste Daroussin memset(¶ms, 0, sizeof(params));
534ffcbc2d7SBaptiste Daroussin params.d = 8;
535ffcbc2d7SBaptiste Daroussin params.steps = 4;
536706cfae4SConrad Meyer params.splitPoint = 1.0;
537fa94c738SConrad Meyer params.shrinkDict = 0;
538fa94c738SConrad Meyer params.shrinkDictMaxRegression = kDefaultRegression;
539706cfae4SConrad Meyer return params;
540706cfae4SConrad Meyer }
541706cfae4SConrad Meyer
defaultFastCoverParams(void)542706cfae4SConrad Meyer static ZDICT_fastCover_params_t defaultFastCoverParams(void)
543706cfae4SConrad Meyer {
544706cfae4SConrad Meyer ZDICT_fastCover_params_t params;
545706cfae4SConrad Meyer memset(¶ms, 0, sizeof(params));
546706cfae4SConrad Meyer params.d = 8;
547706cfae4SConrad Meyer params.f = 20;
548706cfae4SConrad Meyer params.steps = 4;
549706cfae4SConrad Meyer params.splitPoint = 0.75; /* different from default splitPoint of cover */
550706cfae4SConrad Meyer params.accel = DEFAULT_ACCEL;
551fa94c738SConrad Meyer params.shrinkDict = 0;
552fa94c738SConrad Meyer params.shrinkDictMaxRegression = kDefaultRegression;
553ffcbc2d7SBaptiste Daroussin return params;
554ffcbc2d7SBaptiste Daroussin }
555a19eddc3SBaptiste Daroussin #endif
556a19eddc3SBaptiste Daroussin
557a19eddc3SBaptiste Daroussin
558706cfae4SConrad Meyer /** parseAdaptParameters() :
559706cfae4SConrad Meyer * reads adapt parameters from *stringPtr (e.g. "--zstd=min=1,max=19) and store them into adaptMinPtr and adaptMaxPtr.
560706cfae4SConrad Meyer * Both adaptMinPtr and adaptMaxPtr must be already allocated and correctly initialized.
561706cfae4SConrad Meyer * There is no guarantee that any of these values will be updated.
562706cfae4SConrad Meyer * @return 1 means that parsing was successful,
563706cfae4SConrad Meyer * @return 0 in case of malformed parameters
564706cfae4SConrad Meyer */
parseAdaptParameters(const char * stringPtr,int * adaptMinPtr,int * adaptMaxPtr)565706cfae4SConrad Meyer static unsigned parseAdaptParameters(const char* stringPtr, int* adaptMinPtr, int* adaptMaxPtr)
566706cfae4SConrad Meyer {
567706cfae4SConrad Meyer for ( ; ;) {
568b3392d84SAllan Jude if (longCommandWArg(&stringPtr, "min=")) { *adaptMinPtr = readIntFromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
569b3392d84SAllan Jude if (longCommandWArg(&stringPtr, "max=")) { *adaptMaxPtr = readIntFromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
570706cfae4SConrad Meyer DISPLAYLEVEL(4, "invalid compression parameter \n");
571706cfae4SConrad Meyer return 0;
572706cfae4SConrad Meyer }
573706cfae4SConrad Meyer if (stringPtr[0] != 0) return 0; /* check the end of string */
574706cfae4SConrad Meyer if (*adaptMinPtr > *adaptMaxPtr) {
575706cfae4SConrad Meyer DISPLAYLEVEL(4, "incoherent adaptation limits \n");
576706cfae4SConrad Meyer return 0;
577706cfae4SConrad Meyer }
578706cfae4SConrad Meyer return 1;
579706cfae4SConrad Meyer }
580706cfae4SConrad Meyer
581706cfae4SConrad Meyer
582a19eddc3SBaptiste Daroussin /** parseCompressionParameters() :
583af73257bSConrad Meyer * reads compression parameters from *stringPtr (e.g. "--zstd=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6") into *params
584a19eddc3SBaptiste Daroussin * @return 1 means that compression parameters were correct
585a19eddc3SBaptiste Daroussin * @return 0 in case of malformed parameters
586a19eddc3SBaptiste Daroussin */
parseCompressionParameters(const char * stringPtr,ZSTD_compressionParameters * params)587a19eddc3SBaptiste Daroussin static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressionParameters* params)
588a19eddc3SBaptiste Daroussin {
589a19eddc3SBaptiste Daroussin for ( ; ;) {
590a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "windowLog=") || longCommandWArg(&stringPtr, "wlog=")) { params->windowLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
591a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "chainLog=") || longCommandWArg(&stringPtr, "clog=")) { params->chainLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
592a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "hashLog=") || longCommandWArg(&stringPtr, "hlog=")) { params->hashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
593a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "searchLog=") || longCommandWArg(&stringPtr, "slog=")) { params->searchLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
594af73257bSConrad Meyer if (longCommandWArg(&stringPtr, "minMatch=") || longCommandWArg(&stringPtr, "mml=")) { params->minMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
595a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "targetLength=") || longCommandWArg(&stringPtr, "tlen=")) { params->targetLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
596affe9eafSBaptiste Daroussin if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
597a19eddc3SBaptiste Daroussin if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
598af73257bSConrad Meyer if (longCommandWArg(&stringPtr, "ldmHashLog=") || longCommandWArg(&stringPtr, "lhlog=")) { g_ldmHashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
599af73257bSConrad Meyer if (longCommandWArg(&stringPtr, "ldmMinMatch=") || longCommandWArg(&stringPtr, "lmml=")) { g_ldmMinMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
600af73257bSConrad Meyer if (longCommandWArg(&stringPtr, "ldmBucketSizeLog=") || longCommandWArg(&stringPtr, "lblog=")) { g_ldmBucketSizeLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
601af73257bSConrad Meyer if (longCommandWArg(&stringPtr, "ldmHashRateLog=") || longCommandWArg(&stringPtr, "lhrlog=")) { g_ldmHashRateLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
60242239e68SConrad Meyer DISPLAYLEVEL(4, "invalid compression parameter \n");
603a19eddc3SBaptiste Daroussin return 0;
604a19eddc3SBaptiste Daroussin }
605a19eddc3SBaptiste Daroussin
60642239e68SConrad Meyer DISPLAYLEVEL(4, "windowLog=%d, chainLog=%d, hashLog=%d, searchLog=%d \n", params->windowLog, params->chainLog, params->hashLog, params->searchLog);
607af73257bSConrad Meyer DISPLAYLEVEL(4, "minMatch=%d, targetLength=%d, strategy=%d \n", params->minMatch, params->targetLength, params->strategy);
608a19eddc3SBaptiste Daroussin if (stringPtr[0] != 0) return 0; /* check the end of string */
609a19eddc3SBaptiste Daroussin return 1;
610a19eddc3SBaptiste Daroussin }
611a19eddc3SBaptiste Daroussin
printVersion(void)612902c8ce7SBaptiste Daroussin static void printVersion(void)
613902c8ce7SBaptiste Daroussin {
614f6ae9767SConrad Meyer if (g_displayLevel < DISPLAY_LEVEL_DEFAULT) {
615f6ae9767SConrad Meyer DISPLAYOUT("%s\n", ZSTD_VERSION_STRING);
616f6ae9767SConrad Meyer return;
617f6ae9767SConrad Meyer }
618f6ae9767SConrad Meyer
619bc64b5ceSConrad Meyer DISPLAYOUT(WELCOME_MESSAGE);
620bc64b5ceSConrad Meyer if (g_displayLevel >= 3) {
621902c8ce7SBaptiste Daroussin /* format support */
622bc64b5ceSConrad Meyer DISPLAYOUT("*** supports: zstd");
623902c8ce7SBaptiste Daroussin #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>0) && (ZSTD_LEGACY_SUPPORT<8)
624bc64b5ceSConrad Meyer DISPLAYOUT(", zstd legacy v0.%d+", ZSTD_LEGACY_SUPPORT);
625902c8ce7SBaptiste Daroussin #endif
626902c8ce7SBaptiste Daroussin #ifdef ZSTD_GZCOMPRESS
627bc64b5ceSConrad Meyer DISPLAYOUT(", gzip");
628902c8ce7SBaptiste Daroussin #endif
629902c8ce7SBaptiste Daroussin #ifdef ZSTD_LZ4COMPRESS
630bc64b5ceSConrad Meyer DISPLAYOUT(", lz4");
631902c8ce7SBaptiste Daroussin #endif
632902c8ce7SBaptiste Daroussin #ifdef ZSTD_LZMACOMPRESS
633bc64b5ceSConrad Meyer DISPLAYOUT(", lzma, xz ");
634902c8ce7SBaptiste Daroussin #endif
635bc64b5ceSConrad Meyer DISPLAYOUT("\n");
636bc64b5ceSConrad Meyer if (g_displayLevel >= 4) {
637902c8ce7SBaptiste Daroussin /* posix support */
638902c8ce7SBaptiste Daroussin #ifdef _POSIX_C_SOURCE
639bc64b5ceSConrad Meyer DISPLAYOUT("_POSIX_C_SOURCE defined: %ldL\n", (long) _POSIX_C_SOURCE);
640902c8ce7SBaptiste Daroussin #endif
641902c8ce7SBaptiste Daroussin #ifdef _POSIX_VERSION
642bc64b5ceSConrad Meyer DISPLAYOUT("_POSIX_VERSION defined: %ldL \n", (long) _POSIX_VERSION);
643902c8ce7SBaptiste Daroussin #endif
644902c8ce7SBaptiste Daroussin #ifdef PLATFORM_POSIX_VERSION
645bc64b5ceSConrad Meyer DISPLAYOUT("PLATFORM_POSIX_VERSION defined: %ldL\n", (long) PLATFORM_POSIX_VERSION);
646902c8ce7SBaptiste Daroussin #endif
647bc64b5ceSConrad Meyer } }
648902c8ce7SBaptiste Daroussin }
649a19eddc3SBaptiste Daroussin
650b3392d84SAllan Jude #define ZSTD_NB_STRATEGIES 9
651b3392d84SAllan Jude static const char* ZSTD_strategyMap[ZSTD_NB_STRATEGIES + 1] = { "", "ZSTD_fast",
652b3392d84SAllan Jude "ZSTD_dfast", "ZSTD_greedy", "ZSTD_lazy", "ZSTD_lazy2", "ZSTD_btlazy2",
653b3392d84SAllan Jude "ZSTD_btopt", "ZSTD_btultra", "ZSTD_btultra2"};
654b3392d84SAllan Jude
655b3392d84SAllan Jude #ifndef ZSTD_NOCOMPRESS
656b3392d84SAllan Jude
printDefaultCParams(const char * filename,const char * dictFileName,int cLevel)657b3392d84SAllan Jude static void printDefaultCParams(const char* filename, const char* dictFileName, int cLevel) {
658b3392d84SAllan Jude unsigned long long fileSize = UTIL_getFileSize(filename);
659b3392d84SAllan Jude const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0;
660b3392d84SAllan Jude const ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, fileSize, dictSize);
661b3392d84SAllan Jude if (fileSize != UTIL_FILESIZE_UNKNOWN) DISPLAY("%s (%u bytes)\n", filename, (unsigned)fileSize);
662b3392d84SAllan Jude else DISPLAY("%s (src size unknown)\n", filename);
663b3392d84SAllan Jude DISPLAY(" - windowLog : %u\n", cParams.windowLog);
664b3392d84SAllan Jude DISPLAY(" - chainLog : %u\n", cParams.chainLog);
665b3392d84SAllan Jude DISPLAY(" - hashLog : %u\n", cParams.hashLog);
666b3392d84SAllan Jude DISPLAY(" - searchLog : %u\n", cParams.searchLog);
667b3392d84SAllan Jude DISPLAY(" - minMatch : %u\n", cParams.minMatch);
668b3392d84SAllan Jude DISPLAY(" - targetLength : %u\n", cParams.targetLength);
669b3392d84SAllan Jude assert(cParams.strategy < ZSTD_NB_STRATEGIES + 1);
670b3392d84SAllan Jude DISPLAY(" - strategy : %s (%u)\n", ZSTD_strategyMap[(int)cParams.strategy], (unsigned)cParams.strategy);
671b3392d84SAllan Jude }
672b3392d84SAllan Jude
printActualCParams(const char * filename,const char * dictFileName,int cLevel,const ZSTD_compressionParameters * cParams)673b3392d84SAllan Jude static void printActualCParams(const char* filename, const char* dictFileName, int cLevel, const ZSTD_compressionParameters* cParams) {
674b3392d84SAllan Jude unsigned long long fileSize = UTIL_getFileSize(filename);
675b3392d84SAllan Jude const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0;
676b3392d84SAllan Jude ZSTD_compressionParameters actualCParams = ZSTD_getCParams(cLevel, fileSize, dictSize);
677b3392d84SAllan Jude assert(g_displayLevel >= 4);
678b3392d84SAllan Jude actualCParams.windowLog = cParams->windowLog == 0 ? actualCParams.windowLog : cParams->windowLog;
679b3392d84SAllan Jude actualCParams.chainLog = cParams->chainLog == 0 ? actualCParams.chainLog : cParams->chainLog;
680b3392d84SAllan Jude actualCParams.hashLog = cParams->hashLog == 0 ? actualCParams.hashLog : cParams->hashLog;
681b3392d84SAllan Jude actualCParams.searchLog = cParams->searchLog == 0 ? actualCParams.searchLog : cParams->searchLog;
682b3392d84SAllan Jude actualCParams.minMatch = cParams->minMatch == 0 ? actualCParams.minMatch : cParams->minMatch;
683b3392d84SAllan Jude actualCParams.targetLength = cParams->targetLength == 0 ? actualCParams.targetLength : cParams->targetLength;
684b3392d84SAllan Jude actualCParams.strategy = cParams->strategy == 0 ? actualCParams.strategy : cParams->strategy;
685b3392d84SAllan Jude DISPLAY("--zstd=wlog=%d,clog=%d,hlog=%d,slog=%d,mml=%d,tlen=%d,strat=%d\n",
686b3392d84SAllan Jude actualCParams.windowLog, actualCParams.chainLog, actualCParams.hashLog, actualCParams.searchLog,
687b3392d84SAllan Jude actualCParams.minMatch, actualCParams.targetLength, actualCParams.strategy);
688b3392d84SAllan Jude }
689b3392d84SAllan Jude
690b3392d84SAllan Jude #endif
691b3392d84SAllan Jude
692af73257bSConrad Meyer /* Environment variables for parameter setting */
693af73257bSConrad Meyer #define ENV_CLEVEL "ZSTD_CLEVEL"
694f6ae9767SConrad Meyer #define ENV_NBTHREADS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */
695af73257bSConrad Meyer
696bc64b5ceSConrad Meyer /* pick up environment variable */
init_cLevel(void)697af73257bSConrad Meyer static int init_cLevel(void) {
698af73257bSConrad Meyer const char* const env = getenv(ENV_CLEVEL);
699bc64b5ceSConrad Meyer if (env != NULL) {
700af73257bSConrad Meyer const char* ptr = env;
701af73257bSConrad Meyer int sign = 1;
702af73257bSConrad Meyer if (*ptr == '-') {
703af73257bSConrad Meyer sign = -1;
704af73257bSConrad Meyer ptr++;
705af73257bSConrad Meyer } else if (*ptr == '+') {
706af73257bSConrad Meyer ptr++;
707af73257bSConrad Meyer }
708af73257bSConrad Meyer
709af73257bSConrad Meyer if ((*ptr>='0') && (*ptr<='9')) {
710af73257bSConrad Meyer unsigned absLevel;
711af73257bSConrad Meyer if (readU32FromCharChecked(&ptr, &absLevel)) {
712af73257bSConrad Meyer DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: numeric value too large \n", ENV_CLEVEL, env);
713af73257bSConrad Meyer return ZSTDCLI_CLEVEL_DEFAULT;
714af73257bSConrad Meyer } else if (*ptr == 0) {
715ea684039SConrad Meyer return sign * (int)absLevel;
716bc64b5ceSConrad Meyer } }
717af73257bSConrad Meyer
718af73257bSConrad Meyer DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid integer value \n", ENV_CLEVEL, env);
719af73257bSConrad Meyer }
720af73257bSConrad Meyer
721af73257bSConrad Meyer return ZSTDCLI_CLEVEL_DEFAULT;
722af73257bSConrad Meyer }
723af73257bSConrad Meyer
724f6ae9767SConrad Meyer #ifdef ZSTD_MULTITHREAD
init_nbThreads(void)725f6ae9767SConrad Meyer static unsigned init_nbThreads(void) {
726f6ae9767SConrad Meyer const char* const env = getenv(ENV_NBTHREADS);
727f6ae9767SConrad Meyer if (env != NULL) {
728f6ae9767SConrad Meyer const char* ptr = env;
729f6ae9767SConrad Meyer if ((*ptr>='0') && (*ptr<='9')) {
730f6ae9767SConrad Meyer unsigned nbThreads;
731f6ae9767SConrad Meyer if (readU32FromCharChecked(&ptr, &nbThreads)) {
732f6ae9767SConrad Meyer DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: numeric value too large \n", ENV_NBTHREADS, env);
733f6ae9767SConrad Meyer return ZSTDCLI_NBTHREADS_DEFAULT;
734f6ae9767SConrad Meyer } else if (*ptr == 0) {
735f6ae9767SConrad Meyer return nbThreads;
736f6ae9767SConrad Meyer }
737f6ae9767SConrad Meyer }
738f6ae9767SConrad Meyer DISPLAYLEVEL(2, "Ignore environment variable setting %s=%s: not a valid unsigned value \n", ENV_NBTHREADS, env);
739f6ae9767SConrad Meyer }
740bc64b5ceSConrad Meyer
741f6ae9767SConrad Meyer return ZSTDCLI_NBTHREADS_DEFAULT;
742f6ae9767SConrad Meyer }
743f6ae9767SConrad Meyer #endif
744f6ae9767SConrad Meyer
745f6ae9767SConrad Meyer #define NEXT_FIELD(ptr) { \
746f6ae9767SConrad Meyer if (*argument == '=') { \
747f6ae9767SConrad Meyer ptr = ++argument; \
748f6ae9767SConrad Meyer argument += strlen(ptr); \
749f6ae9767SConrad Meyer } else { \
750f6ae9767SConrad Meyer argNb++; \
751f6ae9767SConrad Meyer if (argNb >= argCount) { \
752f6ae9767SConrad Meyer DISPLAY("error: missing command argument \n"); \
753f6ae9767SConrad Meyer CLEAN_RETURN(1); \
754f6ae9767SConrad Meyer } \
755f6ae9767SConrad Meyer ptr = argv[argNb]; \
756f6ae9767SConrad Meyer assert(ptr != NULL); \
757f6ae9767SConrad Meyer if (ptr[0]=='-') { \
758f6ae9767SConrad Meyer DISPLAY("error: command cannot be separated from its argument by another command \n"); \
759f6ae9767SConrad Meyer CLEAN_RETURN(1); \
760f6ae9767SConrad Meyer } } }
761f6ae9767SConrad Meyer
762f6ae9767SConrad Meyer #define NEXT_UINT32(val32) { \
763f6ae9767SConrad Meyer const char* __nb; \
764f6ae9767SConrad Meyer NEXT_FIELD(__nb); \
765f6ae9767SConrad Meyer val32 = readU32FromChar(&__nb); \
766f6ae9767SConrad Meyer }
767f6ae9767SConrad Meyer
768affe9eafSBaptiste Daroussin typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode;
769a19eddc3SBaptiste Daroussin
770a19eddc3SBaptiste Daroussin #define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
771a19eddc3SBaptiste Daroussin
772706cfae4SConrad Meyer #ifdef ZSTD_NOCOMPRESS
773706cfae4SConrad Meyer /* symbols from compression library are not defined and should not be invoked */
774bc64b5ceSConrad Meyer # define MINCLEVEL -99
775706cfae4SConrad Meyer # define MAXCLEVEL 22
776706cfae4SConrad Meyer #else
777706cfae4SConrad Meyer # define MINCLEVEL ZSTD_minCLevel()
778706cfae4SConrad Meyer # define MAXCLEVEL ZSTD_maxCLevel()
779706cfae4SConrad Meyer #endif
780706cfae4SConrad Meyer
main(int argCount,const char * argv[])781b3392d84SAllan Jude int main(int argCount, const char* argv[])
782a19eddc3SBaptiste Daroussin {
783a19eddc3SBaptiste Daroussin int argNb,
784ffcbc2d7SBaptiste Daroussin followLinks = 0,
785b3392d84SAllan Jude allowBlockDevices = 0,
786b3392d84SAllan Jude forceStdin = 0,
78742239e68SConrad Meyer forceStdout = 0,
788f6ae9767SConrad Meyer hasStdout = 0,
78942239e68SConrad Meyer ldmFlag = 0,
790a19eddc3SBaptiste Daroussin main_pause = 0,
79142239e68SConrad Meyer nbWorkers = 0,
792706cfae4SConrad Meyer adapt = 0,
793b3392d84SAllan Jude useRowMatchFinder = 0,
794706cfae4SConrad Meyer adaptMin = MINCLEVEL,
795706cfae4SConrad Meyer adaptMax = MAXCLEVEL,
796af73257bSConrad Meyer rsyncable = 0,
797a19eddc3SBaptiste Daroussin nextArgumentsAreFiles = 0,
79842239e68SConrad Meyer operationResult = 0,
7991767cc49SConrad Meyer separateFiles = 0,
80042239e68SConrad Meyer setRealTimePrio = 0,
80142239e68SConrad Meyer singleThread = 0,
802b3392d84SAllan Jude #ifdef ZSTD_MULTITHREAD
803b3392d84SAllan Jude defaultLogicalCores = 0,
804b3392d84SAllan Jude #endif
805bc64b5ceSConrad Meyer showDefaultCParams = 0,
806bc64b5ceSConrad Meyer ultra=0,
807bc64b5ceSConrad Meyer contentSize=1;
808706cfae4SConrad Meyer double compressibility = 0.5;
809a19eddc3SBaptiste Daroussin unsigned bench_nbSeconds = 3; /* would be better if this value was synchronized from bench */
810a19eddc3SBaptiste Daroussin size_t blockSize = 0;
8113f774a5eSConrad Meyer
8123f774a5eSConrad Meyer FIO_prefs_t* const prefs = FIO_createPreferences();
813f6ae9767SConrad Meyer FIO_ctx_t* const fCtx = FIO_createContext();
814a19eddc3SBaptiste Daroussin zstd_operation_mode operation = zom_compress;
815a19eddc3SBaptiste Daroussin ZSTD_compressionParameters compressionParams;
816bc64b5ceSConrad Meyer int cLevel = init_cLevel();
817bc64b5ceSConrad Meyer int cLevelLast = MINCLEVEL - 1; /* lower than minimum */
818a19eddc3SBaptiste Daroussin unsigned recursive = 0;
819a19eddc3SBaptiste Daroussin unsigned memLimit = 0;
820bc64b5ceSConrad Meyer FileNamesTable* filenames = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */
821bc64b5ceSConrad Meyer FileNamesTable* file_of_names = UTIL_allocateFileNamesTable((size_t)argCount); /* argCount >= 1 */
822a19eddc3SBaptiste Daroussin const char* programName = argv[0];
823a19eddc3SBaptiste Daroussin const char* outFileName = NULL;
824ea684039SConrad Meyer const char* outDirName = NULL;
825f6ae9767SConrad Meyer const char* outMirroredDirName = NULL;
826a19eddc3SBaptiste Daroussin const char* dictFileName = NULL;
827bc64b5ceSConrad Meyer const char* patchFromDictFileName = NULL;
828a19eddc3SBaptiste Daroussin const char* suffix = ZSTD_EXTENSION;
829a19eddc3SBaptiste Daroussin unsigned maxDictSize = g_defaultMaxDictSize;
830a19eddc3SBaptiste Daroussin unsigned dictID = 0;
831ea684039SConrad Meyer size_t streamSrcSize = 0;
832fa94c738SConrad Meyer size_t targetCBlockSize = 0;
833ea684039SConrad Meyer size_t srcSizeHint = 0;
834a19eddc3SBaptiste Daroussin int dictCLevel = g_defaultDictCLevel;
835a19eddc3SBaptiste Daroussin unsigned dictSelect = g_defaultSelectivityLevel;
836a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
837affe9eafSBaptiste Daroussin ZDICT_cover_params_t coverParams = defaultCoverParams();
838706cfae4SConrad Meyer ZDICT_fastCover_params_t fastCoverParams = defaultFastCoverParams();
839706cfae4SConrad Meyer dictType dict = fastCover;
840706cfae4SConrad Meyer #endif
841706cfae4SConrad Meyer #ifndef ZSTD_NOBENCH
842706cfae4SConrad Meyer BMK_advancedParams_t benchParams = BMK_initAdvancedParams();
843a19eddc3SBaptiste Daroussin #endif
844b3392d84SAllan Jude ZSTD_paramSwitch_e literalCompressionMode = ZSTD_ps_auto;
845a19eddc3SBaptiste Daroussin
846653667f9SBaptiste Daroussin
847a19eddc3SBaptiste Daroussin /* init */
848b3392d84SAllan Jude checkLibVersion();
849a19eddc3SBaptiste Daroussin (void)recursive; (void)cLevelLast; /* not used when ZSTD_NOBENCH set */
850bc64b5ceSConrad Meyer (void)memLimit;
851bc64b5ceSConrad Meyer assert(argCount >= 1);
852bc64b5ceSConrad Meyer if ((filenames==NULL) || (file_of_names==NULL)) { DISPLAY("zstd: allocation error \n"); exit(1); }
853ffcbc2d7SBaptiste Daroussin programName = lastNameFromPath(programName);
85442239e68SConrad Meyer #ifdef ZSTD_MULTITHREAD
855f6ae9767SConrad Meyer nbWorkers = init_nbThreads();
85642239e68SConrad Meyer #endif
857a19eddc3SBaptiste Daroussin
858a19eddc3SBaptiste Daroussin /* preset behaviors */
859706cfae4SConrad Meyer if (exeNameMatch(programName, ZSTD_ZSTDMT)) nbWorkers=0, singleThread=0;
860ffcbc2d7SBaptiste Daroussin if (exeNameMatch(programName, ZSTD_UNZSTD)) operation=zom_decompress;
861fa94c738SConrad Meyer if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */
862fa94c738SConrad Meyer 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 */
8633f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_GZ)) { suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like gzip */
8643f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; FIO_setRemoveSrcFile(prefs, 1); } /* behave like gunzip, also supports multiple formats */
865fa94c738SConrad Meyer 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 */
8663f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; FIO_setCompressionType(prefs, FIO_lzmaCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like lzma */
8673f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_UNLZMA)) { operation=zom_decompress; FIO_setCompressionType(prefs, FIO_lzmaCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like unlzma, also supports multiple formats */
8683f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_XZ)) { suffix = XZ_EXTENSION; FIO_setCompressionType(prefs, FIO_xzCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like xz */
8693f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_UNXZ)) { operation=zom_decompress; FIO_setCompressionType(prefs, FIO_xzCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like unxz, also supports multiple formats */
8703f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_LZ4)) { suffix = LZ4_EXTENSION; FIO_setCompressionType(prefs, FIO_lz4Compression); } /* behave like lz4 */
8713f774a5eSConrad Meyer if (exeNameMatch(programName, ZSTD_UNLZ4)) { operation=zom_decompress; FIO_setCompressionType(prefs, FIO_lz4Compression); } /* behave like unlz4, also supports multiple formats */
872a19eddc3SBaptiste Daroussin memset(&compressionParams, 0, sizeof(compressionParams));
873a19eddc3SBaptiste Daroussin
874706cfae4SConrad Meyer /* init crash handler */
875706cfae4SConrad Meyer FIO_addAbortHandler();
876706cfae4SConrad Meyer
877a19eddc3SBaptiste Daroussin /* command switches */
878a19eddc3SBaptiste Daroussin for (argNb=1; argNb<argCount; argNb++) {
879a19eddc3SBaptiste Daroussin const char* argument = argv[argNb];
880a19eddc3SBaptiste Daroussin if (!argument) continue; /* Protection if argument empty */
881a19eddc3SBaptiste Daroussin
882bc64b5ceSConrad Meyer if (nextArgumentsAreFiles) {
883bc64b5ceSConrad Meyer UTIL_refFilename(filenames, argument);
884bc64b5ceSConrad Meyer continue;
885bc64b5ceSConrad Meyer }
886bc64b5ceSConrad Meyer
887a19eddc3SBaptiste Daroussin /* "-" means stdin/stdout */
888a19eddc3SBaptiste Daroussin if (!strcmp(argument, "-")){
889bc64b5ceSConrad Meyer UTIL_refFilename(filenames, stdinmark);
890a19eddc3SBaptiste Daroussin continue;
891bc64b5ceSConrad Meyer }
892a19eddc3SBaptiste Daroussin
893a19eddc3SBaptiste Daroussin /* Decode commands (note : aggregated commands are allowed) */
894a19eddc3SBaptiste Daroussin if (argument[0]=='-') {
895a19eddc3SBaptiste Daroussin
896a19eddc3SBaptiste Daroussin if (argument[1]=='-') {
897a19eddc3SBaptiste Daroussin /* long commands (--long-word) */
898a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--")) { nextArgumentsAreFiles=1; continue; } /* only file names allowed from now on */
899affe9eafSBaptiste Daroussin if (!strcmp(argument, "--list")) { operation=zom_list; continue; }
900a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; }
901a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; }
902a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; }
903b3392d84SAllan Jude if (!strcmp(argument, "--force")) { FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=1; continue; }
904bc64b5ceSConrad Meyer if (!strcmp(argument, "--version")) { printVersion(); CLEAN_RETURN(0); }
905bc64b5ceSConrad Meyer if (!strcmp(argument, "--help")) { usage_advanced(programName); CLEAN_RETURN(0); }
906ffcbc2d7SBaptiste Daroussin if (!strcmp(argument, "--verbose")) { g_displayLevel++; continue; }
907ffcbc2d7SBaptiste Daroussin if (!strcmp(argument, "--quiet")) { g_displayLevel--; continue; }
908ffcbc2d7SBaptiste Daroussin if (!strcmp(argument, "--stdout")) { forceStdout=1; outFileName=stdoutmark; g_displayLevel-=(g_displayLevel==2); continue; }
909a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--ultra")) { ultra=1; continue; }
9103f774a5eSConrad Meyer if (!strcmp(argument, "--check")) { FIO_setChecksumFlag(prefs, 2); continue; }
9113f774a5eSConrad Meyer if (!strcmp(argument, "--no-check")) { FIO_setChecksumFlag(prefs, 0); continue; }
9123f774a5eSConrad Meyer if (!strcmp(argument, "--sparse")) { FIO_setSparseWrite(prefs, 2); continue; }
9133f774a5eSConrad Meyer if (!strcmp(argument, "--no-sparse")) { FIO_setSparseWrite(prefs, 0); continue; }
914a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--test")) { operation=zom_test; continue; }
915706cfae4SConrad Meyer if (!strcmp(argument, "--train")) { operation=zom_train; if (outFileName==NULL) outFileName=g_defaultDictName; continue; }
9163f774a5eSConrad Meyer if (!strcmp(argument, "--no-dictID")) { FIO_setDictIDFlag(prefs, 0); continue; }
9173f774a5eSConrad Meyer if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(prefs, 0); continue; }
9183f774a5eSConrad Meyer if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(prefs, 1); continue; }
919a19eddc3SBaptiste Daroussin if (!strcmp(argument, "--priority=rt")) { setRealTimePrio = 1; continue; }
920bc64b5ceSConrad Meyer if (!strcmp(argument, "--show-default-cparams")) { showDefaultCParams = 1; continue; }
921bc64b5ceSConrad Meyer if (!strcmp(argument, "--content-size")) { contentSize = 1; continue; }
922bc64b5ceSConrad Meyer if (!strcmp(argument, "--no-content-size")) { contentSize = 0; continue; }
923706cfae4SConrad Meyer if (!strcmp(argument, "--adapt")) { adapt = 1; continue; }
924b3392d84SAllan Jude if (!strcmp(argument, "--no-row-match-finder")) { useRowMatchFinder = 1; continue; }
925b3392d84SAllan Jude if (!strcmp(argument, "--row-match-finder")) { useRowMatchFinder = 2; continue; }
926bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--adapt=")) { adapt = 1; if (!parseAdaptParameters(argument, &adaptMin, &adaptMax)) { badusage(programName); CLEAN_RETURN(1); } continue; }
92742239e68SConrad Meyer if (!strcmp(argument, "--single-thread")) { nbWorkers = 0; singleThread = 1; continue; }
9283f774a5eSConrad Meyer if (!strcmp(argument, "--format=zstd")) { suffix = ZSTD_EXTENSION; FIO_setCompressionType(prefs, FIO_zstdCompression); continue; }
929a19eddc3SBaptiste Daroussin #ifdef ZSTD_GZCOMPRESS
9303f774a5eSConrad Meyer if (!strcmp(argument, "--format=gzip")) { suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); continue; }
931a19eddc3SBaptiste Daroussin #endif
932a19eddc3SBaptiste Daroussin #ifdef ZSTD_LZMACOMPRESS
9333f774a5eSConrad Meyer if (!strcmp(argument, "--format=lzma")) { suffix = LZMA_EXTENSION; FIO_setCompressionType(prefs, FIO_lzmaCompression); continue; }
9343f774a5eSConrad Meyer if (!strcmp(argument, "--format=xz")) { suffix = XZ_EXTENSION; FIO_setCompressionType(prefs, FIO_xzCompression); continue; }
935a19eddc3SBaptiste Daroussin #endif
936ffcbc2d7SBaptiste Daroussin #ifdef ZSTD_LZ4COMPRESS
9373f774a5eSConrad Meyer if (!strcmp(argument, "--format=lz4")) { suffix = LZ4_EXTENSION; FIO_setCompressionType(prefs, FIO_lz4Compression); continue; }
938ffcbc2d7SBaptiste Daroussin #endif
939af73257bSConrad Meyer if (!strcmp(argument, "--rsyncable")) { rsyncable = 1; continue; }
940b3392d84SAllan Jude if (!strcmp(argument, "--compress-literals")) { literalCompressionMode = ZSTD_ps_enable; continue; }
941b3392d84SAllan Jude if (!strcmp(argument, "--no-compress-literals")) { literalCompressionMode = ZSTD_ps_disable; continue; }
942b3392d84SAllan Jude if (!strcmp(argument, "--no-progress")) { FIO_setProgressSetting(FIO_ps_never); continue; }
943b3392d84SAllan Jude if (!strcmp(argument, "--progress")) { FIO_setProgressSetting(FIO_ps_always); continue; }
944ea684039SConrad Meyer if (!strcmp(argument, "--exclude-compressed")) { FIO_setExcludeCompressedFile(prefs, 1); continue; }
945f6ae9767SConrad Meyer
946a19eddc3SBaptiste Daroussin /* long commands with arguments */
947a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
948ffcbc2d7SBaptiste Daroussin if (longCommandWArg(&argument, "--train-cover")) {
949ffcbc2d7SBaptiste Daroussin operation = zom_train;
950706cfae4SConrad Meyer if (outFileName == NULL)
951ffcbc2d7SBaptiste Daroussin outFileName = g_defaultDictName;
952706cfae4SConrad Meyer dict = cover;
953a19eddc3SBaptiste Daroussin /* Allow optional arguments following an = */
954a19eddc3SBaptiste Daroussin if (*argument == 0) { memset(&coverParams, 0, sizeof(coverParams)); }
955bc64b5ceSConrad Meyer else if (*argument++ != '=') { badusage(programName); CLEAN_RETURN(1); }
956bc64b5ceSConrad Meyer else if (!parseCoverParameters(argument, &coverParams)) { badusage(programName); CLEAN_RETURN(1); }
957a19eddc3SBaptiste Daroussin continue;
958a19eddc3SBaptiste Daroussin }
959706cfae4SConrad Meyer if (longCommandWArg(&argument, "--train-fastcover")) {
960706cfae4SConrad Meyer operation = zom_train;
961706cfae4SConrad Meyer if (outFileName == NULL)
962706cfae4SConrad Meyer outFileName = g_defaultDictName;
963706cfae4SConrad Meyer dict = fastCover;
964706cfae4SConrad Meyer /* Allow optional arguments following an = */
965706cfae4SConrad Meyer if (*argument == 0) { memset(&fastCoverParams, 0, sizeof(fastCoverParams)); }
966bc64b5ceSConrad Meyer else if (*argument++ != '=') { badusage(programName); CLEAN_RETURN(1); }
967bc64b5ceSConrad Meyer else if (!parseFastCoverParameters(argument, &fastCoverParams)) { badusage(programName); CLEAN_RETURN(1); }
968706cfae4SConrad Meyer continue;
969706cfae4SConrad Meyer }
970ffcbc2d7SBaptiste Daroussin if (longCommandWArg(&argument, "--train-legacy")) {
971ffcbc2d7SBaptiste Daroussin operation = zom_train;
972706cfae4SConrad Meyer if (outFileName == NULL)
973ffcbc2d7SBaptiste Daroussin outFileName = g_defaultDictName;
974706cfae4SConrad Meyer dict = legacy;
975ffcbc2d7SBaptiste Daroussin /* Allow optional arguments following an = */
976ffcbc2d7SBaptiste Daroussin if (*argument == 0) { continue; }
977bc64b5ceSConrad Meyer else if (*argument++ != '=') { badusage(programName); CLEAN_RETURN(1); }
978bc64b5ceSConrad Meyer else if (!parseLegacyParameters(argument, &dictSelect)) { badusage(programName); CLEAN_RETURN(1); }
979ffcbc2d7SBaptiste Daroussin continue;
980ffcbc2d7SBaptiste Daroussin }
981a19eddc3SBaptiste Daroussin #endif
982f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--threads")) { NEXT_UINT32(nbWorkers); continue; }
983f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--memlimit")) { NEXT_UINT32(memLimit); continue; }
984f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--memory")) { NEXT_UINT32(memLimit); continue; }
985f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--memlimit-decompress")) { NEXT_UINT32(memLimit); continue; }
986bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--block-size=")) { blockSize = readSizeTFromChar(&argument); continue; }
987f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--maxdict")) { NEXT_UINT32(maxDictSize); continue; }
988f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--dictID")) { NEXT_UINT32(dictID); continue; }
989bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--zstd=")) { if (!parseCompressionParameters(argument, &compressionParams)) { badusage(programName); CLEAN_RETURN(1); } continue; }
990bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--stream-size=")) { streamSrcSize = readSizeTFromChar(&argument); continue; }
991bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--target-compressed-block-size=")) { targetCBlockSize = readSizeTFromChar(&argument); continue; }
992bc64b5ceSConrad Meyer if (longCommandWArg(&argument, "--size-hint=")) { srcSizeHint = readSizeTFromChar(&argument); continue; }
993f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--output-dir-flat")) { NEXT_FIELD(outDirName); continue; }
994b3392d84SAllan Jude #ifdef ZSTD_MULTITHREAD
995b3392d84SAllan Jude if (longCommandWArg(&argument, "--auto-threads")) {
996b3392d84SAllan Jude const char* threadDefault = NULL;
997b3392d84SAllan Jude NEXT_FIELD(threadDefault);
998b3392d84SAllan Jude if (strcmp(threadDefault, "logical") == 0)
999b3392d84SAllan Jude defaultLogicalCores = 1;
1000b3392d84SAllan Jude continue;
1001b3392d84SAllan Jude }
1002b3392d84SAllan Jude #endif
1003f6ae9767SConrad Meyer #ifdef UTIL_HAS_MIRRORFILELIST
1004f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--output-dir-mirror")) { NEXT_FIELD(outMirroredDirName); continue; }
1005f6ae9767SConrad Meyer #endif
1006b3392d84SAllan Jude #ifndef ZSTD_NOTRACE
1007b3392d84SAllan Jude if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; }
1008b3392d84SAllan Jude #endif
1009f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; }
1010653667f9SBaptiste Daroussin if (longCommandWArg(&argument, "--long")) {
1011653667f9SBaptiste Daroussin unsigned ldmWindowLog = 0;
1012653667f9SBaptiste Daroussin ldmFlag = 1;
1013653667f9SBaptiste Daroussin /* Parse optional window log */
1014653667f9SBaptiste Daroussin if (*argument == '=') {
1015653667f9SBaptiste Daroussin ++argument;
1016653667f9SBaptiste Daroussin ldmWindowLog = readU32FromChar(&argument);
1017653667f9SBaptiste Daroussin } else if (*argument != 0) {
1018653667f9SBaptiste Daroussin /* Invalid character following --long */
1019bc64b5ceSConrad Meyer badusage(programName);
1020bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1021653667f9SBaptiste Daroussin }
1022653667f9SBaptiste Daroussin /* Only set windowLog if not already set by --zstd */
1023653667f9SBaptiste Daroussin if (compressionParams.windowLog == 0)
1024653667f9SBaptiste Daroussin compressionParams.windowLog = ldmWindowLog;
1025653667f9SBaptiste Daroussin continue;
1026653667f9SBaptiste Daroussin }
1027706cfae4SConrad Meyer #ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */
102842239e68SConrad Meyer if (longCommandWArg(&argument, "--fast")) {
1029706cfae4SConrad Meyer /* Parse optional acceleration factor */
103042239e68SConrad Meyer if (*argument == '=') {
1031706cfae4SConrad Meyer U32 const maxFast = (U32)-ZSTD_minCLevel();
103242239e68SConrad Meyer U32 fastLevel;
103342239e68SConrad Meyer ++argument;
103442239e68SConrad Meyer fastLevel = readU32FromChar(&argument);
1035706cfae4SConrad Meyer if (fastLevel > maxFast) fastLevel = maxFast;
1036706cfae4SConrad Meyer if (fastLevel) {
1037706cfae4SConrad Meyer dictCLevel = cLevel = -(int)fastLevel;
1038706cfae4SConrad Meyer } else {
1039bc64b5ceSConrad Meyer badusage(programName);
1040bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1041706cfae4SConrad Meyer }
104242239e68SConrad Meyer } else if (*argument != 0) {
104342239e68SConrad Meyer /* Invalid character following --fast */
1044bc64b5ceSConrad Meyer badusage(programName);
1045bc64b5ceSConrad Meyer CLEAN_RETURN(1);
104642239e68SConrad Meyer } else {
104742239e68SConrad Meyer cLevel = -1; /* default for --fast */
104842239e68SConrad Meyer }
104942239e68SConrad Meyer continue;
105042239e68SConrad Meyer }
1051706cfae4SConrad Meyer #endif
1052bc64b5ceSConrad Meyer
1053f6ae9767SConrad Meyer if (longCommandWArg(&argument, "--filelist")) {
1054f6ae9767SConrad Meyer const char* listName;
1055f6ae9767SConrad Meyer NEXT_FIELD(listName);
1056f6ae9767SConrad Meyer UTIL_refFilename(file_of_names, listName);
1057bc64b5ceSConrad Meyer continue;
1058bc64b5ceSConrad Meyer }
1059bc64b5ceSConrad Meyer
1060a19eddc3SBaptiste Daroussin /* fall-through, will trigger bad_usage() later on */
1061a19eddc3SBaptiste Daroussin }
1062a19eddc3SBaptiste Daroussin
1063a19eddc3SBaptiste Daroussin argument++;
1064a19eddc3SBaptiste Daroussin while (argument[0]!=0) {
1065f6ae9767SConrad Meyer
1066a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOCOMPRESS
1067a19eddc3SBaptiste Daroussin /* compression Level */
1068a19eddc3SBaptiste Daroussin if ((*argument>='0') && (*argument<='9')) {
1069ea684039SConrad Meyer dictCLevel = cLevel = (int)readU32FromChar(&argument);
1070a19eddc3SBaptiste Daroussin continue;
1071a19eddc3SBaptiste Daroussin }
1072a19eddc3SBaptiste Daroussin #endif
1073a19eddc3SBaptiste Daroussin
1074a19eddc3SBaptiste Daroussin switch(argument[0])
1075a19eddc3SBaptiste Daroussin {
1076a19eddc3SBaptiste Daroussin /* Display help */
1077bc64b5ceSConrad Meyer case 'V': printVersion(); CLEAN_RETURN(0); /* Version Only */
1078a19eddc3SBaptiste Daroussin case 'H':
1079bc64b5ceSConrad Meyer case 'h': usage_advanced(programName); CLEAN_RETURN(0);
1080a19eddc3SBaptiste Daroussin
1081a19eddc3SBaptiste Daroussin /* Compress */
1082a19eddc3SBaptiste Daroussin case 'z': operation=zom_compress; argument++; break;
1083a19eddc3SBaptiste Daroussin
1084a19eddc3SBaptiste Daroussin /* Decoding */
1085a19eddc3SBaptiste Daroussin case 'd':
1086a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
1087706cfae4SConrad Meyer benchParams.mode = BMK_decodeOnly;
108842239e68SConrad Meyer if (operation==zom_bench) { argument++; break; } /* benchmark decode (hidden option) */
1089a19eddc3SBaptiste Daroussin #endif
1090a19eddc3SBaptiste Daroussin operation=zom_decompress; argument++; break;
1091a19eddc3SBaptiste Daroussin
1092a19eddc3SBaptiste Daroussin /* Force stdout, even if stdout==console */
1093a19eddc3SBaptiste Daroussin case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break;
1094a19eddc3SBaptiste Daroussin
1095a19eddc3SBaptiste Daroussin /* Use file content as dictionary */
1096f6ae9767SConrad Meyer case 'D': argument++; NEXT_FIELD(dictFileName); break;
1097a19eddc3SBaptiste Daroussin
1098a19eddc3SBaptiste Daroussin /* Overwrite */
1099b3392d84SAllan Jude case 'f': FIO_overwriteMode(prefs); forceStdin=1; forceStdout=1; followLinks=1; allowBlockDevices=1; argument++; break;
1100a19eddc3SBaptiste Daroussin
1101a19eddc3SBaptiste Daroussin /* Verbose mode */
1102ffcbc2d7SBaptiste Daroussin case 'v': g_displayLevel++; argument++; break;
1103a19eddc3SBaptiste Daroussin
1104a19eddc3SBaptiste Daroussin /* Quiet mode */
1105ffcbc2d7SBaptiste Daroussin case 'q': g_displayLevel--; argument++; break;
1106a19eddc3SBaptiste Daroussin
1107ffcbc2d7SBaptiste Daroussin /* keep source file (default) */
11083f774a5eSConrad Meyer case 'k': FIO_setRemoveSrcFile(prefs, 0); argument++; break;
1109a19eddc3SBaptiste Daroussin
1110a19eddc3SBaptiste Daroussin /* Checksum */
11113f774a5eSConrad Meyer case 'C': FIO_setChecksumFlag(prefs, 2); argument++; break;
1112a19eddc3SBaptiste Daroussin
1113a19eddc3SBaptiste Daroussin /* test compressed file */
1114a19eddc3SBaptiste Daroussin case 't': operation=zom_test; argument++; break;
1115a19eddc3SBaptiste Daroussin
1116a19eddc3SBaptiste Daroussin /* destination file name */
1117f6ae9767SConrad Meyer case 'o': argument++; NEXT_FIELD(outFileName); break;
1118a19eddc3SBaptiste Daroussin
1119bc64b5ceSConrad Meyer /* limit memory */
1120a19eddc3SBaptiste Daroussin case 'M':
1121a19eddc3SBaptiste Daroussin argument++;
1122a19eddc3SBaptiste Daroussin memLimit = readU32FromChar(&argument);
1123a19eddc3SBaptiste Daroussin break;
1124affe9eafSBaptiste Daroussin case 'l': operation=zom_list; argument++; break;
1125a19eddc3SBaptiste Daroussin #ifdef UTIL_HAS_CREATEFILELIST
1126a19eddc3SBaptiste Daroussin /* recursive */
1127a19eddc3SBaptiste Daroussin case 'r': recursive=1; argument++; break;
1128a19eddc3SBaptiste Daroussin #endif
1129a19eddc3SBaptiste Daroussin
1130a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
1131a19eddc3SBaptiste Daroussin /* Benchmark */
1132a19eddc3SBaptiste Daroussin case 'b':
1133a19eddc3SBaptiste Daroussin operation=zom_bench;
1134a19eddc3SBaptiste Daroussin argument++;
1135a19eddc3SBaptiste Daroussin break;
1136a19eddc3SBaptiste Daroussin
1137a19eddc3SBaptiste Daroussin /* range bench (benchmark only) */
1138a19eddc3SBaptiste Daroussin case 'e':
1139a19eddc3SBaptiste Daroussin /* compression Level */
1140a19eddc3SBaptiste Daroussin argument++;
1141ea684039SConrad Meyer cLevelLast = (int)readU32FromChar(&argument);
1142a19eddc3SBaptiste Daroussin break;
1143a19eddc3SBaptiste Daroussin
1144a19eddc3SBaptiste Daroussin /* Modify Nb Iterations (benchmark only) */
1145a19eddc3SBaptiste Daroussin case 'i':
1146a19eddc3SBaptiste Daroussin argument++;
1147a19eddc3SBaptiste Daroussin bench_nbSeconds = readU32FromChar(&argument);
1148a19eddc3SBaptiste Daroussin break;
1149a19eddc3SBaptiste Daroussin
1150a19eddc3SBaptiste Daroussin /* cut input into blocks (benchmark only) */
1151a19eddc3SBaptiste Daroussin case 'B':
1152a19eddc3SBaptiste Daroussin argument++;
1153a19eddc3SBaptiste Daroussin blockSize = readU32FromChar(&argument);
1154a19eddc3SBaptiste Daroussin break;
1155a19eddc3SBaptiste Daroussin
11561767cc49SConrad Meyer /* benchmark files separately (hidden option) */
11571767cc49SConrad Meyer case 'S':
11581767cc49SConrad Meyer argument++;
11591767cc49SConrad Meyer separateFiles = 1;
11601767cc49SConrad Meyer break;
11611767cc49SConrad Meyer
1162a19eddc3SBaptiste Daroussin #endif /* ZSTD_NOBENCH */
1163a19eddc3SBaptiste Daroussin
1164a19eddc3SBaptiste Daroussin /* nb of threads (hidden option) */
1165a19eddc3SBaptiste Daroussin case 'T':
1166a19eddc3SBaptiste Daroussin argument++;
1167ea684039SConrad Meyer nbWorkers = (int)readU32FromChar(&argument);
1168a19eddc3SBaptiste Daroussin break;
1169a19eddc3SBaptiste Daroussin
1170a19eddc3SBaptiste Daroussin /* Dictionary Selection level */
1171a19eddc3SBaptiste Daroussin case 's':
1172a19eddc3SBaptiste Daroussin argument++;
1173a19eddc3SBaptiste Daroussin dictSelect = readU32FromChar(&argument);
1174a19eddc3SBaptiste Daroussin break;
1175a19eddc3SBaptiste Daroussin
1176a19eddc3SBaptiste Daroussin /* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
1177a19eddc3SBaptiste Daroussin case 'p': argument++;
1178a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
1179a19eddc3SBaptiste Daroussin if ((*argument>='0') && (*argument<='9')) {
1180706cfae4SConrad Meyer benchParams.additionalParam = (int)readU32FromChar(&argument);
1181a19eddc3SBaptiste Daroussin } else
1182a19eddc3SBaptiste Daroussin #endif
1183a19eddc3SBaptiste Daroussin main_pause=1;
1184a19eddc3SBaptiste Daroussin break;
1185706cfae4SConrad Meyer
1186706cfae4SConrad Meyer /* Select compressibility of synthetic sample */
1187706cfae4SConrad Meyer case 'P':
1188f6ae9767SConrad Meyer argument++;
1189706cfae4SConrad Meyer compressibility = (double)readU32FromChar(&argument) / 100;
1190706cfae4SConrad Meyer break;
1191706cfae4SConrad Meyer
1192a19eddc3SBaptiste Daroussin /* unknown command */
1193bc64b5ceSConrad Meyer default : badusage(programName); CLEAN_RETURN(1);
1194a19eddc3SBaptiste Daroussin }
1195a19eddc3SBaptiste Daroussin }
1196a19eddc3SBaptiste Daroussin continue;
1197a19eddc3SBaptiste Daroussin } /* if (argument[0]=='-') */
1198a19eddc3SBaptiste Daroussin
1199bc64b5ceSConrad Meyer /* none of the above : add filename to list */
1200bc64b5ceSConrad Meyer UTIL_refFilename(filenames, argument);
1201a19eddc3SBaptiste Daroussin }
1202a19eddc3SBaptiste Daroussin
1203a19eddc3SBaptiste Daroussin /* Welcome message (if verbose) */
1204a19eddc3SBaptiste Daroussin DISPLAYLEVEL(3, WELCOME_MESSAGE);
1205a19eddc3SBaptiste Daroussin
120642239e68SConrad Meyer #ifdef ZSTD_MULTITHREAD
120742239e68SConrad Meyer if ((nbWorkers==0) && (!singleThread)) {
120842239e68SConrad Meyer /* automatically set # workers based on # of reported cpus */
1209b3392d84SAllan Jude if (defaultLogicalCores) {
1210b3392d84SAllan Jude nbWorkers = UTIL_countLogicalCores();
1211b3392d84SAllan Jude DISPLAYLEVEL(3, "Note: %d logical core(s) detected \n", nbWorkers);
1212b3392d84SAllan Jude } else {
121342239e68SConrad Meyer nbWorkers = UTIL_countPhysicalCores();
121442239e68SConrad Meyer DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbWorkers);
1215ffcbc2d7SBaptiste Daroussin }
1216b3392d84SAllan Jude }
1217706cfae4SConrad Meyer #else
1218706cfae4SConrad Meyer (void)singleThread; (void)nbWorkers;
121942239e68SConrad Meyer #endif
1220ffcbc2d7SBaptiste Daroussin
1221ffcbc2d7SBaptiste Daroussin g_utilDisplayLevel = g_displayLevel;
1222b3392d84SAllan Jude
1223b3392d84SAllan Jude #ifdef UTIL_HAS_CREATEFILELIST
1224ffcbc2d7SBaptiste Daroussin if (!followLinks) {
1225bc64b5ceSConrad Meyer unsigned u, fileNamesNb;
1226bc64b5ceSConrad Meyer unsigned const nbFilenames = (unsigned)filenames->tableSize;
1227bc64b5ceSConrad Meyer for (u=0, fileNamesNb=0; u<nbFilenames; u++) {
1228bc64b5ceSConrad Meyer if ( UTIL_isLink(filenames->fileNames[u])
1229bc64b5ceSConrad Meyer && !UTIL_isFIFO(filenames->fileNames[u])
1230ea684039SConrad Meyer ) {
1231bc64b5ceSConrad Meyer DISPLAYLEVEL(2, "Warning : %s is a symbolic link, ignoring \n", filenames->fileNames[u]);
1232ffcbc2d7SBaptiste Daroussin } else {
1233bc64b5ceSConrad Meyer filenames->fileNames[fileNamesNb++] = filenames->fileNames[u];
1234bc64b5ceSConrad Meyer } }
1235bc64b5ceSConrad Meyer if (fileNamesNb == 0 && nbFilenames > 0) /* all names are eliminated */
12363f774a5eSConrad Meyer CLEAN_RETURN(1);
1237bc64b5ceSConrad Meyer filenames->tableSize = fileNamesNb;
1238bc64b5ceSConrad Meyer } /* if (!followLinks) */
1239bc64b5ceSConrad Meyer
1240bc64b5ceSConrad Meyer /* read names from a file */
1241bc64b5ceSConrad Meyer if (file_of_names->tableSize) {
1242bc64b5ceSConrad Meyer size_t const nbFileLists = file_of_names->tableSize;
1243bc64b5ceSConrad Meyer size_t flNb;
1244bc64b5ceSConrad Meyer for (flNb=0; flNb < nbFileLists; flNb++) {
1245bc64b5ceSConrad Meyer FileNamesTable* const fnt = UTIL_createFileNamesTable_fromFileName(file_of_names->fileNames[flNb]);
1246bc64b5ceSConrad Meyer if (fnt==NULL) {
1247bc64b5ceSConrad Meyer DISPLAYLEVEL(1, "zstd: error reading %s \n", file_of_names->fileNames[flNb]);
1248bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1249ffcbc2d7SBaptiste Daroussin }
1250bc64b5ceSConrad Meyer filenames = UTIL_mergeFileNamesTable(filenames, fnt);
1251bc64b5ceSConrad Meyer }
1252bc64b5ceSConrad Meyer }
1253bc64b5ceSConrad Meyer
1254a19eddc3SBaptiste Daroussin if (recursive) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */
1255bc64b5ceSConrad Meyer UTIL_expandFNT(&filenames, followLinks);
1256a19eddc3SBaptiste Daroussin }
1257706cfae4SConrad Meyer #else
1258706cfae4SConrad Meyer (void)followLinks;
1259a19eddc3SBaptiste Daroussin #endif
1260902c8ce7SBaptiste Daroussin
1261affe9eafSBaptiste Daroussin if (operation == zom_list) {
1262902c8ce7SBaptiste Daroussin #ifndef ZSTD_NODECOMPRESS
1263bc64b5ceSConrad Meyer int const ret = FIO_listMultipleFiles((unsigned)filenames->tableSize, filenames->fileNames, g_displayLevel);
1264affe9eafSBaptiste Daroussin CLEAN_RETURN(ret);
1265902c8ce7SBaptiste Daroussin #else
1266902c8ce7SBaptiste Daroussin DISPLAY("file information is not supported \n");
1267902c8ce7SBaptiste Daroussin CLEAN_RETURN(1);
1268902c8ce7SBaptiste Daroussin #endif
1269affe9eafSBaptiste Daroussin }
1270902c8ce7SBaptiste Daroussin
1271a19eddc3SBaptiste Daroussin /* Check if benchmark is selected */
1272a19eddc3SBaptiste Daroussin if (operation==zom_bench) {
1273a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOBENCH
1274706cfae4SConrad Meyer benchParams.blockSize = blockSize;
1275706cfae4SConrad Meyer benchParams.nbWorkers = nbWorkers;
1276ea684039SConrad Meyer benchParams.realTime = (unsigned)setRealTimePrio;
1277706cfae4SConrad Meyer benchParams.nbSeconds = bench_nbSeconds;
1278706cfae4SConrad Meyer benchParams.ldmFlag = ldmFlag;
1279ea684039SConrad Meyer benchParams.ldmMinMatch = (int)g_ldmMinMatch;
1280ea684039SConrad Meyer benchParams.ldmHashLog = (int)g_ldmHashLog;
1281b3392d84SAllan Jude benchParams.useRowMatchFinder = useRowMatchFinder;
1282653667f9SBaptiste Daroussin if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) {
1283ea684039SConrad Meyer benchParams.ldmBucketSizeLog = (int)g_ldmBucketSizeLog;
1284653667f9SBaptiste Daroussin }
1285af73257bSConrad Meyer if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) {
1286ea684039SConrad Meyer benchParams.ldmHashRateLog = (int)g_ldmHashRateLog;
1287653667f9SBaptiste Daroussin }
12883f774a5eSConrad Meyer benchParams.literalCompressionMode = literalCompressionMode;
1289706cfae4SConrad Meyer
1290706cfae4SConrad Meyer if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
1291706cfae4SConrad Meyer if (cLevelLast > ZSTD_maxCLevel()) cLevelLast = ZSTD_maxCLevel();
1292706cfae4SConrad Meyer if (cLevelLast < cLevel) cLevelLast = cLevel;
1293706cfae4SConrad Meyer if (cLevelLast > cLevel)
1294706cfae4SConrad Meyer DISPLAYLEVEL(3, "Benchmarking levels from %d to %d\n", cLevel, cLevelLast);
1295bc64b5ceSConrad Meyer if (filenames->tableSize > 0) {
1296706cfae4SConrad Meyer if(separateFiles) {
1297706cfae4SConrad Meyer unsigned i;
1298bc64b5ceSConrad Meyer for(i = 0; i < filenames->tableSize; i++) {
1299706cfae4SConrad Meyer int c;
1300bc64b5ceSConrad Meyer DISPLAYLEVEL(3, "Benchmarking %s \n", filenames->fileNames[i]);
1301706cfae4SConrad Meyer for(c = cLevel; c <= cLevelLast; c++) {
1302bc64b5ceSConrad Meyer BMK_benchFilesAdvanced(&filenames->fileNames[i], 1, dictFileName, c, &compressionParams, g_displayLevel, &benchParams);
1303bc64b5ceSConrad Meyer } }
1304706cfae4SConrad Meyer } else {
1305706cfae4SConrad Meyer for(; cLevel <= cLevelLast; cLevel++) {
1306bc64b5ceSConrad Meyer BMK_benchFilesAdvanced(filenames->fileNames, (unsigned)filenames->tableSize, dictFileName, cLevel, &compressionParams, g_displayLevel, &benchParams);
1307bc64b5ceSConrad Meyer } }
1308706cfae4SConrad Meyer } else {
1309706cfae4SConrad Meyer for(; cLevel <= cLevelLast; cLevel++) {
1310706cfae4SConrad Meyer BMK_syntheticTest(cLevel, compressibility, &compressionParams, g_displayLevel, &benchParams);
1311bc64b5ceSConrad Meyer } }
1312706cfae4SConrad Meyer
13131767cc49SConrad Meyer #else
1314706cfae4SConrad Meyer (void)bench_nbSeconds; (void)blockSize; (void)setRealTimePrio; (void)separateFiles; (void)compressibility;
1315a19eddc3SBaptiste Daroussin #endif
1316a19eddc3SBaptiste Daroussin goto _end;
1317a19eddc3SBaptiste Daroussin }
1318a19eddc3SBaptiste Daroussin
1319a19eddc3SBaptiste Daroussin /* Check if dictionary builder is selected */
1320a19eddc3SBaptiste Daroussin if (operation==zom_train) {
1321a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODICT
1322affe9eafSBaptiste Daroussin ZDICT_params_t zParams;
1323affe9eafSBaptiste Daroussin zParams.compressionLevel = dictCLevel;
1324ea684039SConrad Meyer zParams.notificationLevel = (unsigned)g_displayLevel;
1325affe9eafSBaptiste Daroussin zParams.dictID = dictID;
1326706cfae4SConrad Meyer if (dict == cover) {
1327ffcbc2d7SBaptiste Daroussin int const optimize = !coverParams.k || !coverParams.d;
1328ea684039SConrad Meyer coverParams.nbThreads = (unsigned)nbWorkers;
1329affe9eafSBaptiste Daroussin coverParams.zParams = zParams;
1330b3392d84SAllan Jude operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize, memLimit);
1331706cfae4SConrad Meyer } else if (dict == fastCover) {
1332706cfae4SConrad Meyer int const optimize = !fastCoverParams.k || !fastCoverParams.d;
1333ea684039SConrad Meyer fastCoverParams.nbThreads = (unsigned)nbWorkers;
1334706cfae4SConrad Meyer fastCoverParams.zParams = zParams;
1335b3392d84SAllan Jude operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize, memLimit);
1336a19eddc3SBaptiste Daroussin } else {
1337affe9eafSBaptiste Daroussin ZDICT_legacy_params_t dictParams;
1338a19eddc3SBaptiste Daroussin memset(&dictParams, 0, sizeof(dictParams));
1339a19eddc3SBaptiste Daroussin dictParams.selectivityLevel = dictSelect;
1340affe9eafSBaptiste Daroussin dictParams.zParams = zParams;
1341b3392d84SAllan Jude operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0, memLimit);
1342a19eddc3SBaptiste Daroussin }
1343706cfae4SConrad Meyer #else
1344706cfae4SConrad Meyer (void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */
1345706cfae4SConrad Meyer DISPLAYLEVEL(1, "training mode not available \n");
1346706cfae4SConrad Meyer operationResult = 1;
1347a19eddc3SBaptiste Daroussin #endif
1348a19eddc3SBaptiste Daroussin goto _end;
1349a19eddc3SBaptiste Daroussin }
1350a19eddc3SBaptiste Daroussin
1351902c8ce7SBaptiste Daroussin #ifndef ZSTD_NODECOMPRESS
1352ea684039SConrad Meyer if (operation==zom_test) { FIO_setTestMode(prefs, 1); outFileName=nulmark; FIO_setRemoveSrcFile(prefs, 0); } /* test mode */
1353902c8ce7SBaptiste Daroussin #endif
1354902c8ce7SBaptiste Daroussin
1355a19eddc3SBaptiste Daroussin /* No input filename ==> use stdin and stdout */
1356bc64b5ceSConrad Meyer if (filenames->tableSize == 0) UTIL_refFilename(filenames, stdinmark);
1357bc64b5ceSConrad Meyer if (!strcmp(filenames->fileNames[0], stdinmark) && !outFileName)
135842239e68SConrad Meyer outFileName = stdoutmark; /* when input is stdin, default output is stdout */
1359a19eddc3SBaptiste Daroussin
1360a19eddc3SBaptiste Daroussin /* Check if input/output defined as console; trigger an error in this case */
1361b3392d84SAllan Jude if (!forceStdin
1362b3392d84SAllan Jude && !strcmp(filenames->fileNames[0], stdinmark)
1363b3392d84SAllan Jude && IS_CONSOLE(stdin) ) {
1364f6ae9767SConrad Meyer DISPLAYLEVEL(1, "stdin is a console, aborting\n");
1365bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1366bc64b5ceSConrad Meyer }
136742239e68SConrad Meyer if ( outFileName && !strcmp(outFileName, stdoutmark)
136842239e68SConrad Meyer && IS_CONSOLE(stdout)
1369bc64b5ceSConrad Meyer && !strcmp(filenames->fileNames[0], stdinmark)
137042239e68SConrad Meyer && !forceStdout
1371bc64b5ceSConrad Meyer && operation!=zom_decompress ) {
1372f6ae9767SConrad Meyer DISPLAYLEVEL(1, "stdout is a console, aborting\n");
1373bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1374bc64b5ceSConrad Meyer }
1375a19eddc3SBaptiste Daroussin
1376a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOCOMPRESS
1377a19eddc3SBaptiste Daroussin /* check compression level limits */
1378a19eddc3SBaptiste Daroussin { int const maxCLevel = ultra ? ZSTD_maxCLevel() : ZSTDCLI_CLEVEL_MAX;
1379a19eddc3SBaptiste Daroussin if (cLevel > maxCLevel) {
1380a19eddc3SBaptiste Daroussin DISPLAYLEVEL(2, "Warning : compression level higher than max, reduced to %i \n", maxCLevel);
1381a19eddc3SBaptiste Daroussin cLevel = maxCLevel;
1382a19eddc3SBaptiste Daroussin } }
1383a19eddc3SBaptiste Daroussin #endif
1384a19eddc3SBaptiste Daroussin
1385bc64b5ceSConrad Meyer if (showDefaultCParams) {
1386bc64b5ceSConrad Meyer if (operation == zom_decompress) {
1387bc64b5ceSConrad Meyer DISPLAY("error : can't use --show-default-cparams in decomrpession mode \n");
1388bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1389bc64b5ceSConrad Meyer }
1390bc64b5ceSConrad Meyer }
1391bc64b5ceSConrad Meyer
1392bc64b5ceSConrad Meyer if (dictFileName != NULL && patchFromDictFileName != NULL) {
1393bc64b5ceSConrad Meyer DISPLAY("error : can't use -D and --patch-from=# at the same time \n");
1394bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1395bc64b5ceSConrad Meyer }
1396bc64b5ceSConrad Meyer
1397bc64b5ceSConrad Meyer if (patchFromDictFileName != NULL && filenames->tableSize > 1) {
1398bc64b5ceSConrad Meyer DISPLAY("error : can't use --patch-from=# on multiple files \n");
1399bc64b5ceSConrad Meyer CLEAN_RETURN(1);
1400bc64b5ceSConrad Meyer }
1401bc64b5ceSConrad Meyer
1402f6ae9767SConrad Meyer /* No status message in pipe mode (stdin - stdout) */
1403f6ae9767SConrad Meyer hasStdout = outFileName && !strcmp(outFileName,stdoutmark);
1404f6ae9767SConrad Meyer
1405b3392d84SAllan Jude if ((hasStdout || !IS_CONSOLE(stderr)) && (g_displayLevel==2)) g_displayLevel=1;
1406a19eddc3SBaptiste Daroussin
1407a19eddc3SBaptiste Daroussin /* IO Stream/File */
1408f6ae9767SConrad Meyer FIO_setHasStdoutOutput(fCtx, hasStdout);
1409f6ae9767SConrad Meyer FIO_setNbFilesTotal(fCtx, (int)filenames->tableSize);
1410f6ae9767SConrad Meyer FIO_determineHasStdinInput(fCtx, filenames);
1411ffcbc2d7SBaptiste Daroussin FIO_setNotificationLevel(g_displayLevel);
1412b3392d84SAllan Jude FIO_setAllowBlockDevices(prefs, allowBlockDevices);
1413bc64b5ceSConrad Meyer FIO_setPatchFromMode(prefs, patchFromDictFileName != NULL);
1414bc64b5ceSConrad Meyer if (memLimit == 0) {
1415bc64b5ceSConrad Meyer if (compressionParams.windowLog == 0) {
1416bc64b5ceSConrad Meyer memLimit = (U32)1 << g_defaultMaxWindowLog;
1417bc64b5ceSConrad Meyer } else {
1418bc64b5ceSConrad Meyer memLimit = (U32)1 << (compressionParams.windowLog & 31);
1419bc64b5ceSConrad Meyer } }
1420bc64b5ceSConrad Meyer if (patchFromDictFileName != NULL)
1421bc64b5ceSConrad Meyer dictFileName = patchFromDictFileName;
1422bc64b5ceSConrad Meyer FIO_setMemLimit(prefs, memLimit);
1423a19eddc3SBaptiste Daroussin if (operation==zom_compress) {
1424a19eddc3SBaptiste Daroussin #ifndef ZSTD_NOCOMPRESS
1425bc64b5ceSConrad Meyer FIO_setContentSize(prefs, contentSize);
14263f774a5eSConrad Meyer FIO_setNbWorkers(prefs, nbWorkers);
1427ea684039SConrad Meyer FIO_setBlockSize(prefs, (int)blockSize);
1428ea684039SConrad Meyer if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(prefs, (int)g_overlapLog);
1429ea684039SConrad Meyer FIO_setLdmFlag(prefs, (unsigned)ldmFlag);
1430ea684039SConrad Meyer FIO_setLdmHashLog(prefs, (int)g_ldmHashLog);
1431ea684039SConrad Meyer FIO_setLdmMinMatch(prefs, (int)g_ldmMinMatch);
1432ea684039SConrad Meyer if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) FIO_setLdmBucketSizeLog(prefs, (int)g_ldmBucketSizeLog);
1433ea684039SConrad Meyer if (g_ldmHashRateLog != LDM_PARAM_DEFAULT) FIO_setLdmHashRateLog(prefs, (int)g_ldmHashRateLog);
1434ea684039SConrad Meyer FIO_setAdaptiveMode(prefs, (unsigned)adapt);
1435b3392d84SAllan Jude FIO_setUseRowMatchFinder(prefs, useRowMatchFinder);
14363f774a5eSConrad Meyer FIO_setAdaptMin(prefs, adaptMin);
14373f774a5eSConrad Meyer FIO_setAdaptMax(prefs, adaptMax);
14383f774a5eSConrad Meyer FIO_setRsyncable(prefs, rsyncable);
1439ea684039SConrad Meyer FIO_setStreamSrcSize(prefs, streamSrcSize);
1440fa94c738SConrad Meyer FIO_setTargetCBlockSize(prefs, targetCBlockSize);
1441ea684039SConrad Meyer FIO_setSrcSizeHint(prefs, srcSizeHint);
14423f774a5eSConrad Meyer FIO_setLiteralCompressionMode(prefs, literalCompressionMode);
1443706cfae4SConrad Meyer if (adaptMin > cLevel) cLevel = adaptMin;
1444706cfae4SConrad Meyer if (adaptMax < cLevel) cLevel = adaptMax;
1445653667f9SBaptiste Daroussin
1446bc64b5ceSConrad Meyer /* Compare strategies constant with the ground truth */
1447bc64b5ceSConrad Meyer { ZSTD_bounds strategyBounds = ZSTD_cParam_getBounds(ZSTD_c_strategy);
1448bc64b5ceSConrad Meyer assert(ZSTD_NB_STRATEGIES == strategyBounds.upperBound);
1449bc64b5ceSConrad Meyer (void)strategyBounds; }
1450bc64b5ceSConrad Meyer
1451b3392d84SAllan Jude if (showDefaultCParams || g_displayLevel >= 4) {
1452bc64b5ceSConrad Meyer size_t fileNb;
1453bc64b5ceSConrad Meyer for (fileNb = 0; fileNb < (size_t)filenames->tableSize; fileNb++) {
1454b3392d84SAllan Jude if (showDefaultCParams)
1455b3392d84SAllan Jude printDefaultCParams(filenames->fileNames[fileNb], dictFileName, cLevel);
1456b3392d84SAllan Jude if (g_displayLevel >= 4)
1457b3392d84SAllan Jude printActualCParams(filenames->fileNames[fileNb], dictFileName, cLevel, &compressionParams);
1458bc64b5ceSConrad Meyer }
1459bc64b5ceSConrad Meyer }
1460bc64b5ceSConrad Meyer
1461b3392d84SAllan Jude if (g_displayLevel >= 4)
1462b3392d84SAllan Jude FIO_displayCompressionParameters(prefs);
1463bc64b5ceSConrad Meyer if ((filenames->tableSize==1) && outFileName)
1464f6ae9767SConrad Meyer operationResult = FIO_compressFilename(fCtx, prefs, outFileName, filenames->fileNames[0], dictFileName, cLevel, compressionParams);
1465a19eddc3SBaptiste Daroussin else
1466f6ae9767SConrad Meyer operationResult = FIO_compressMultipleFilenames(fCtx, prefs, filenames->fileNames, outMirroredDirName, outDirName, outFileName, suffix, dictFileName, cLevel, compressionParams);
1467a19eddc3SBaptiste Daroussin #else
1468b3392d84SAllan Jude (void)contentSize; (void)suffix; (void)adapt; (void)rsyncable; (void)ultra; (void)cLevel; (void)ldmFlag; (void)literalCompressionMode; (void)targetCBlockSize; (void)streamSrcSize; (void)srcSizeHint; (void)ZSTD_strategyMap; (void)useRowMatchFinder; /* not used when ZSTD_NOCOMPRESS set */
1469a19eddc3SBaptiste Daroussin DISPLAY("Compression not supported \n");
1470a19eddc3SBaptiste Daroussin #endif
1471a19eddc3SBaptiste Daroussin } else { /* decompression or test */
1472a19eddc3SBaptiste Daroussin #ifndef ZSTD_NODECOMPRESS
1473bc64b5ceSConrad Meyer if (filenames->tableSize == 1 && outFileName) {
1474f6ae9767SConrad Meyer operationResult = FIO_decompressFilename(fCtx, prefs, outFileName, filenames->fileNames[0], dictFileName);
1475bc64b5ceSConrad Meyer } else {
1476f6ae9767SConrad Meyer operationResult = FIO_decompressMultipleFilenames(fCtx, prefs, filenames->fileNames, outMirroredDirName, outDirName, outFileName, dictFileName);
1477653667f9SBaptiste Daroussin }
1478a19eddc3SBaptiste Daroussin #else
1479a19eddc3SBaptiste Daroussin DISPLAY("Decompression not supported \n");
1480a19eddc3SBaptiste Daroussin #endif
1481a19eddc3SBaptiste Daroussin }
1482a19eddc3SBaptiste Daroussin
1483a19eddc3SBaptiste Daroussin _end:
14843f774a5eSConrad Meyer FIO_freePreferences(prefs);
1485f6ae9767SConrad Meyer FIO_freeContext(fCtx);
1486a19eddc3SBaptiste Daroussin if (main_pause) waitEnter();
1487bc64b5ceSConrad Meyer UTIL_freeFileNamesTable(filenames);
1488bc64b5ceSConrad Meyer UTIL_freeFileNamesTable(file_of_names);
1489b3392d84SAllan Jude #ifndef ZSTD_NOTRACE
1490b3392d84SAllan Jude TRACE_finish();
1491b3392d84SAllan Jude #endif
1492bc64b5ceSConrad Meyer
1493a19eddc3SBaptiste Daroussin return operationResult;
1494a19eddc3SBaptiste Daroussin }
1495