2017-08-18 16:52:05 -07:00
/*
2021-03-29 14:23:36 -07:00
* Copyright ( c ) Yann Collet , Facebook , Inc .
2016-08-30 10:04:33 -07:00
* All rights reserved .
*
2017-08-18 16:52:05 -07:00
* This source code is licensed under both the BSD - style license ( found in the
* LICENSE file in the root directory of this source tree ) and the GPLv2 ( found
* in the COPYING file in the root directory of this source tree ) .
2017-09-08 00:09:23 -07:00
* You may select , at your option , one of the above - listed licenses .
2016-08-30 10:04:33 -07:00
*/
2016-08-28 10:00:49 -07:00
2016-05-28 20:16:05 -07:00
2016-07-13 05:15:08 -07:00
/*-************************************
* Tuning parameters
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-07-13 06:16:00 -07:00
# ifndef ZSTDCLI_CLEVEL_DEFAULT
# define ZSTDCLI_CLEVEL_DEFAULT 3
2016-07-13 05:15:08 -07:00
# endif
2016-08-12 09:04:15 -07:00
# ifndef ZSTDCLI_CLEVEL_MAX
2017-08-19 13:33:50 -07:00
# define ZSTDCLI_CLEVEL_MAX 19 /* without using --ultra */
2016-08-12 09:04:15 -07:00
# endif
2020-09-09 09:35:40 -07:00
# ifndef ZSTDCLI_NBTHREADS_DEFAULT
# define ZSTDCLI_NBTHREADS_DEFAULT 1
2020-09-07 15:11:42 -07:00
# endif
2017-01-25 17:01:13 -08:00
2016-05-28 20:16:05 -07:00
/*-************************************
2016-11-16 08:50:54 -08:00
* Dependencies
2016-05-28 20:16:05 -07:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-12-21 06:08:44 -08:00
# include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */
# include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
2018-12-19 13:26:27 -08:00
# include <stdlib.h> /* getenv */
2016-05-28 20:16:05 -07:00
# include <string.h> /* strcmp, strlen */
2019-12-02 14:28:18 -08:00
# include <stdio.h> /* fprintf(), stdin, stdout, stderr */
2016-07-04 09:16:16 -07:00
# include <errno.h> /* errno */
2019-12-02 14:28:18 -08:00
# include <assert.h> /* assert */
2017-08-19 13:33:50 -07:00
# include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOBENCH
2018-11-13 11:01:59 -08:00
# include "benchzstd.h" /* BMK_benchFiles */
2016-05-28 20:16:05 -07:00
# endif
# ifndef ZSTD_NODICT
2017-08-19 13:33:50 -07:00
# include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */
2016-05-28 20:16:05 -07:00
# endif
2021-02-03 19:53:00 -08:00
# ifndef ZSTD_NOTRACE
# include "zstdcli_trace.h"
# endif
2020-05-01 13:20:40 -07:00
# include "../lib/zstd.h" /* ZSTD_VERSION_STRING, ZSTD_minCLevel, ZSTD_maxCLevel */
2016-05-28 20:16:05 -07:00
/*-************************************
* Constants
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define COMPRESSOR_NAME "zstd command line interface"
# ifndef ZSTD_VERSION
# define ZSTD_VERSION "v" ZSTD_VERSION_STRING
# endif
# define AUTHOR "Yann Collet"
# define WELCOME_MESSAGE "*** %s %i-bits %s, by %s ***\n", COMPRESSOR_NAME, (int)(sizeof(size_t)*8), ZSTD_VERSION, AUTHOR
2017-04-14 11:33:04 -07:00
# define ZSTD_ZSTDMT "zstdmt"
2016-05-28 20:16:05 -07:00
# define ZSTD_UNZSTD "unzstd"
2017-02-14 10:45:19 -08:00
# define ZSTD_CAT "zstdcat"
2018-01-19 11:26:35 -08:00
# define ZSTD_ZCAT "zcat"
2017-02-14 10:45:19 -08:00
# define ZSTD_GZ "gzip"
# define ZSTD_GUNZIP "gunzip"
# define ZSTD_GZCAT "gzcat"
2017-03-13 18:11:07 -07:00
# define ZSTD_LZMA "lzma"
2017-06-26 11:24:36 -07:00
# define ZSTD_UNLZMA "unlzma"
2017-03-13 18:11:07 -07:00
# define ZSTD_XZ "xz"
2017-06-26 11:24:36 -07:00
# define ZSTD_UNXZ "unxz"
2017-09-28 16:18:15 -07:00
# define ZSTD_LZ4 "lz4"
# define ZSTD_UNLZ4 "unlz4"
2016-05-28 20:16:05 -07:00
# define KB *(1 <<10)
# define MB *(1 <<20)
# define GB *(1U<<30)
2017-08-19 13:33:50 -07:00
# define DISPLAY_LEVEL_DEFAULT 2
2016-08-12 14:49:05 -07:00
2016-05-28 20:16:05 -07:00
static const char * g_defaultDictName = " dictionary " ;
static const unsigned g_defaultMaxDictSize = 110 KB ;
2016-09-01 15:05:57 -07:00
static const int g_defaultDictCLevel = 3 ;
2016-05-28 20:16:05 -07:00
static const unsigned g_defaultSelectivityLevel = 9 ;
2017-09-22 14:04:39 -07:00
static const unsigned g_defaultMaxWindowLog = 27 ;
2017-01-30 14:37:08 -08:00
# define OVERLAP_LOG_DEFAULT 9999
2017-09-02 21:10:36 -07:00
# define LDM_PARAM_DEFAULT 9999 /* Default for parameters where 0 is valid */
2017-01-30 14:37:08 -08:00
static U32 g_overlapLog = OVERLAP_LOG_DEFAULT ;
2017-09-01 14:52:51 -07:00
static U32 g_ldmHashLog = 0 ;
static U32 g_ldmMinMatch = 0 ;
2018-11-21 14:36:57 -08:00
static U32 g_ldmHashRateLog = LDM_PARAM_DEFAULT ;
2017-09-02 21:10:36 -07:00
static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT ;
2016-05-28 20:16:05 -07:00
2018-08-23 12:06:20 -07:00
# define DEFAULT_ACCEL 1
typedef enum { cover , fastCover , legacy } dictType ;
2016-05-28 20:16:05 -07:00
/*-************************************
* Display Macros
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-12-02 16:08:08 -08:00
# define DISPLAY_F(f, ...) fprintf((f), __VA_ARGS__)
# define DISPLAYOUT(...) DISPLAY_F(stdout, __VA_ARGS__)
# define DISPLAY(...) DISPLAY_F(stderr, __VA_ARGS__)
2017-03-23 11:13:52 -07:00
# define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
2017-08-19 13:33:50 -07:00
static int g_displayLevel = DISPLAY_LEVEL_DEFAULT ; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
2016-05-28 20:16:05 -07:00
2021-01-07 10:37:27 -08:00
/*-************************************
* Check Version ( when CLI linked to dynamic library )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Due to usage of experimental symbols and capabilities by the CLI,
* the CLI must be linked against a dynamic library of same version */
static void checkLibVersion ( void )
{
if ( strcmp ( ZSTD_VERSION_STRING , ZSTD_versionString ( ) ) ) {
DISPLAYLEVEL ( 1 , " Error : incorrect library version (expecting : %s ; actual : %s ) \n " ,
ZSTD_VERSION_STRING , ZSTD_versionString ( ) ) ;
DISPLAYLEVEL ( 1 , " Please update library to version %s, or use stand-alone zstd binary \n " ,
ZSTD_VERSION_STRING ) ;
exit ( 1 ) ;
}
}
2016-05-28 20:16:05 -07:00
/*-************************************
* Command Line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-12-02 16:08:08 -08:00
/* print help either in `stderr` or `stdout` depending on originating request
* error ( badusage ) = > stderr
* help ( usage_advanced ) = > stdout
*/
static void usage ( FILE * f , const char * programName )
2016-05-28 20:16:05 -07:00
{
2019-12-02 16:08:08 -08:00
DISPLAY_F ( f , " Usage : \n " ) ;
DISPLAY_F ( f , " %s [args] [FILE(s)] [-o file] \n " , programName ) ;
DISPLAY_F ( f , " \n " ) ;
DISPLAY_F ( f , " FILE : a filename \n " ) ;
DISPLAY_F ( f , " with no FILE, or when FILE is - , read standard input \n " ) ;
DISPLAY_F ( f , " Arguments : \n " ) ;
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOCOMPRESS
2019-12-02 16:08:08 -08:00
DISPLAY_F ( f , " -# : # compression level (1-%d, default: %d) \n " , ZSTDCLI_CLEVEL_MAX , ZSTDCLI_CLEVEL_DEFAULT ) ;
2016-05-28 20:16:05 -07:00
# endif
# ifndef ZSTD_NODECOMPRESS
2019-12-02 16:08:08 -08:00
DISPLAY_F ( f , " -d : decompression \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
2020-05-08 14:14:46 -07:00
DISPLAY_F ( f , " -D DICT: use DICT as Dictionary for compression or decompression \n " ) ;
2020-05-08 14:20:47 -07:00
DISPLAY_F ( f , " -o file: result stored into `file` (only 1 output file) \n " ) ;
2021-01-11 14:53:20 -08:00
DISPLAY_F ( f , " -f : disable input and output checks. Allows overwriting existing files, \n " ) ;
2021-05-04 13:24:46 -07:00
DISPLAY_F ( f , " input from console, output to stdout, operating on links, \n " ) ;
DISPLAY_F ( f , " block devices, etc. \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAY_F ( f , " --rm : remove source file(s) after successful de/compression \n " ) ;
DISPLAY_F ( f , " -k : preserve source file(s) (default) \n " ) ;
DISPLAY_F ( f , " -h/-H : display help/long help and exit \n " ) ;
2016-05-28 20:16:05 -07:00
}
2019-12-02 16:08:08 -08:00
static void usage_advanced ( const char * programName )
2016-05-28 20:16:05 -07:00
{
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( WELCOME_MESSAGE ) ;
usage ( stdout , programName ) ;
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Advanced arguments : \n " ) ;
DISPLAYOUT ( " -V : display Version number and exit \n " ) ;
2020-05-08 14:14:46 -07:00
2021-11-29 11:10:43 -08:00
DISPLAYOUT ( " -c : write to standard output (even if it is the console) \n " ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " -v : verbose mode; specify multiple times to increase verbosity \n " ) ;
DISPLAYOUT ( " -q : suppress warnings; specify twice to suppress errors too \n " ) ;
2021-05-06 11:50:28 -07:00
DISPLAYOUT ( " --[no-]progress : forcibly display, or never display the progress counter. \n " ) ;
DISPLAYOUT ( " note: any (de)compressed output to terminal will mix with progress counter text. \n " ) ;
2020-05-08 14:14:46 -07:00
# ifdef UTIL_HAS_CREATEFILELIST
DISPLAYOUT ( " -r : operate recursively on directories \n " ) ;
2020-07-23 12:10:57 -07:00
DISPLAYOUT ( " --filelist FILE : read list of files to operate upon from FILE \n " ) ;
DISPLAYOUT ( " --output-dir-flat DIR : processed files are stored into DIR \n " ) ;
2020-05-08 14:14:46 -07:00
# endif
2020-06-19 19:35:51 -07:00
# ifdef UTIL_HAS_MIRRORFILELIST
2020-07-23 12:10:57 -07:00
DISPLAYOUT ( " --output-dir-mirror DIR : processed files are stored into DIR respecting original directory structure \n " ) ;
2020-06-19 19:35:51 -07:00
# endif
2020-08-24 13:14:19 -07:00
# ifndef ZSTD_NOCOMPRESS
DISPLAYOUT ( " --[no-]check : during compression, add XXH64 integrity checksum to frame (default: enabled) " ) ;
# ifndef ZSTD_NODECOMPRESS
DISPLAYOUT ( " . If specified with -d, decompressor will ignore/validate checksums in compressed frame (default: validate). " ) ;
# endif
2020-08-24 14:36:36 -07:00
# else
2020-08-24 13:14:19 -07:00
# ifdef ZSTD_NOCOMPRESS
DISPLAYOUT ( " --[no-]check : during decompression, ignore/validate checksums in compressed frame (default: validate). " ) ;
# endif
2020-08-24 14:36:36 -07:00
# endif /* ZSTD_NOCOMPRESS */
2021-02-03 19:53:00 -08:00
# ifndef ZSTD_NOTRACE
2021-02-17 09:26:38 -08:00
DISPLAYOUT ( " \n " ) ;
2021-02-03 19:53:00 -08:00
DISPLAYOUT ( " --trace FILE : log tracing information to FILE. " ) ;
# endif
2020-08-24 13:14:19 -07:00
DISPLAYOUT ( " \n " ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " -- : All arguments after \" -- \" are treated as files \n " ) ;
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOCOMPRESS
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Advanced compression arguments : \n " ) ;
DISPLAYOUT ( " --ultra : enable levels beyond %i, up to %i (requires more memory) \n " , ZSTDCLI_CLEVEL_MAX , ZSTD_maxCLevel ( ) ) ;
DISPLAYOUT ( " --long[=#]: enable long distance matching with given window log (default: %u) \n " , g_defaultMaxWindowLog ) ;
DISPLAYOUT ( " --fast[=#]: switch to very fast compression levels (default: %u) \n " , 1 ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --adapt : dynamically adapt compression level to I/O conditions \n " ) ;
2020-11-02 17:52:29 -08:00
DISPLAYOUT ( " --[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n " ) ;
2021-06-03 08:12:27 -07:00
DISPLAYOUT ( " --patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n " ) ;
2019-12-02 16:08:08 -08:00
# ifdef ZSTD_MULTITHREAD
DISPLAYOUT ( " -T# : spawns # compression threads (default: 1, 0==# cores) \n " ) ;
DISPLAYOUT ( " -B# : select size of each job (default: 0==automatic) \n " ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " --single-thread : use a single thread for both I/O and compression (result slightly different than -T1) \n " ) ;
2021-06-16 06:38:43 -07:00
DISPLAYOUT ( " --auto-threads={physical,logical} (default: physical} : use either physical cores or logical cores as default when specifying -T0 \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --rsyncable : compress using a rsync-friendly method (-B sets block size) \n " ) ;
# endif
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " --exclude-compressed: only compress files that are not already compressed \n " ) ;
DISPLAYOUT ( " --stream-size=# : specify size of streaming input from `stdin` \n " ) ;
DISPLAYOUT ( " --size-hint=# optimize compression parameters for streaming input of approximately this size \n " ) ;
DISPLAYOUT ( " --target-compressed-block-size=# : generate compressed block of approximately targeted size \n " ) ;
DISPLAYOUT ( " --no-dictID : don't write dictID into header (dictionary compression only) \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --[no-]compress-literals : force (un)compressed literals \n " ) ;
2020-05-08 14:14:46 -07:00
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --format=zstd : compress files to the .zst format (default) \n " ) ;
2017-02-08 06:17:55 -08:00
# ifdef ZSTD_GZCOMPRESS
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --format=gzip : compress files to the .gz format \n " ) ;
2017-02-08 06:17:55 -08:00
# endif
2017-03-13 18:11:07 -07:00
# ifdef ZSTD_LZMACOMPRESS
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --format=xz : compress files to the .xz format \n " ) ;
DISPLAYOUT ( " --format=lzma : compress files to the .lzma format \n " ) ;
2017-03-13 18:11:07 -07:00
# endif
2017-04-24 16:48:25 -07:00
# ifdef ZSTD_LZ4COMPRESS
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --format=lz4 : compress files to the .lz4 format \n " ) ;
2017-04-24 16:48:25 -07:00
# endif
2020-05-08 14:14:46 -07:00
# endif /* !ZSTD_NOCOMPRESS */
2016-05-30 17:29:45 -07:00
# ifndef ZSTD_NODECOMPRESS
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Advanced decompression arguments : \n " ) ;
DISPLAYOUT ( " -l : print information about zstd compressed files \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --test : test compressed file integrity \n " ) ;
DISPLAYOUT ( " -M# : Set a memory usage limit for decompression \n " ) ;
2020-05-08 14:14:46 -07:00
# if ZSTD_SPARSE_DEFAULT
DISPLAYOUT ( " --[no-]sparse : sparse mode (default: enabled on file, disabled on stdout) \n " ) ;
# else
DISPLAYOUT ( " --[no-]sparse : sparse mode (default: disabled) \n " ) ;
# endif
# endif /* ZSTD_NODECOMPRESS */
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NODICT
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Dictionary builder : \n " ) ;
DISPLAYOUT ( " --train ## : create a dictionary from a training set of files \n " ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " --train-cover[=k=#,d=#,steps=#,split=#,shrink[=#]] : use the cover algorithm with optional args \n " ) ;
DISPLAYOUT ( " --train-fastcover[=k=#,d=#,f=#,steps=#,split=#,accel=#,shrink[=#]] : use the fast cover algorithm with optional args \n " ) ;
DISPLAYOUT ( " --train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u) \n " , g_defaultSelectivityLevel ) ;
DISPLAYOUT ( " -o DICT : DICT is dictionary name (default: %s) \n " , g_defaultDictName ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --maxdict=# : limit dictionary to specified size (default: %u) \n " , g_defaultMaxDictSize ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " --dictID=# : force dictionary ID to specified value (default: random) \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
2020-05-08 14:14:46 -07:00
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOBENCH
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Benchmark arguments : \n " ) ;
DISPLAYOUT ( " -b# : benchmark file(s), using # compression level (default: %d) \n " , ZSTDCLI_CLEVEL_DEFAULT ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " -e# : test all compression levels successively from -b# to -e# (default: 1) \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " -i# : minimum evaluation time in seconds (default: 3s) \n " ) ;
2020-05-08 14:14:46 -07:00
DISPLAYOUT ( " -B# : cut file into independent blocks of size # (default: no block) \n " ) ;
DISPLAYOUT ( " -S : output one benchmark result per input file (default: consolidated result) \n " ) ;
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " --priority=rt : set process priority to real-time \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
2020-05-08 14:14:46 -07:00
2016-05-28 20:16:05 -07:00
}
2019-12-02 16:08:08 -08:00
static void badusage ( const char * programName )
2016-05-28 20:16:05 -07:00
{
2019-12-02 16:08:08 -08:00
DISPLAYLEVEL ( 1 , " Incorrect parameters \n " ) ;
if ( g_displayLevel > = 2 ) usage ( stderr , programName ) ;
2016-05-28 20:16:05 -07:00
}
static void waitEnter ( void )
{
int unused ;
2019-12-02 16:08:08 -08:00
DISPLAY ( " Press enter to continue... \n " ) ;
2016-05-28 20:16:05 -07:00
unused = getchar ( ) ;
( void ) unused ;
}
2017-03-24 17:06:09 -07:00
static const char * lastNameFromPath ( const char * path )
{
const char * name = path ;
if ( strrchr ( name , ' / ' ) ) name = strrchr ( name , ' / ' ) + 1 ;
if ( strrchr ( name , ' \\ ' ) ) name = strrchr ( name , ' \\ ' ) + 1 ; /* windows */
return name ;
}
/*! exeNameMatch() :
@ return : a non - zero value if exeName matches test , excluding the extension
*/
static int exeNameMatch ( const char * exeName , const char * test )
{
return ! strncmp ( exeName , test , strlen ( test ) ) & &
( exeName [ strlen ( test ) ] = = ' \0 ' | | exeName [ strlen ( test ) ] = = ' . ' ) ;
}
2018-05-12 14:29:33 -07:00
static void errorOut ( const char * msg )
{
DISPLAY ( " %s \n " , msg ) ; exit ( 1 ) ;
}
2018-12-19 23:41:18 -08:00
/*! readU32FromCharChecked() :
2018-12-19 16:45:42 -08:00
* @ return 0 if success , and store the result in * value .
2018-03-11 19:56:48 -07:00
* allows and interprets K , KB , KiB , M , MB and MiB suffix .
* Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
2018-12-19 16:45:42 -08:00
* @ return 1 if an overflow error occurs */
2018-12-19 23:41:18 -08:00
static int readU32FromCharChecked ( const char * * stringPtr , unsigned * value )
2016-06-03 06:14:09 -07:00
{
unsigned result = 0 ;
2018-05-12 14:29:33 -07:00
while ( ( * * stringPtr > = ' 0 ' ) & & ( * * stringPtr < = ' 9 ' ) ) {
2020-02-18 15:30:59 -08:00
unsigned const max = ( ( unsigned ) ( - 1 ) ) / 10 ;
unsigned last = result ;
2019-04-10 10:03:06 -07:00
if ( result > max ) return 1 ; /* overflow error */
result * = 10 ;
result + = ( unsigned ) ( * * stringPtr - ' 0 ' ) ;
2020-02-18 15:30:59 -08:00
if ( result < last ) return 1 ; /* overflow error */
2019-04-10 10:03:06 -07:00
( * stringPtr ) + + ;
2018-05-12 14:29:33 -07:00
}
2016-10-17 17:48:48 -07:00
if ( ( * * stringPtr = = ' K ' ) | | ( * * stringPtr = = ' M ' ) ) {
2018-05-12 14:29:33 -07:00
unsigned const maxK = ( ( unsigned ) ( - 1 ) ) > > 10 ;
2019-04-10 10:03:06 -07:00
if ( result > maxK ) return 1 ; /* overflow error */
2016-10-17 17:48:48 -07:00
result < < = 10 ;
2018-05-12 14:29:33 -07:00
if ( * * stringPtr = = ' M ' ) {
2019-04-10 10:03:06 -07:00
if ( result > maxK ) return 1 ; /* overflow error */
2018-05-12 14:29:33 -07:00
result < < = 10 ;
}
( * stringPtr ) + + ; /* skip `K` or `M` */
2016-10-17 17:48:48 -07:00
if ( * * stringPtr = = ' i ' ) ( * stringPtr ) + + ;
if ( * * stringPtr = = ' B ' ) ( * stringPtr ) + + ;
}
2018-12-19 16:45:42 -08:00
* value = result ;
return 0 ;
}
/*! readU32FromChar() :
* @ return : unsigned integer value read from input in ` char ` format .
* allows and interprets K , KB , KiB , M , MB and MiB suffix .
* Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
* Note : function will exit ( ) program if digit sequence overflows */
static unsigned readU32FromChar ( const char * * stringPtr ) {
2020-02-20 11:29:58 -08:00
static const char errorMsg [ ] = " error: numeric value overflows 32-bit unsigned int " ;
2018-12-19 16:45:42 -08:00
unsigned result ;
2018-12-19 23:41:18 -08:00
if ( readU32FromCharChecked ( stringPtr , & result ) ) { errorOut ( errorMsg ) ; }
2016-06-03 06:14:09 -07:00
return result ;
}
2021-06-09 13:49:36 -07:00
/*! readIntFromChar() :
* @ return : signed integer value read from input in ` char ` format .
* allows and interprets K , KB , KiB , M , MB and MiB suffix .
* Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
* Note : function will exit ( ) program if digit sequence overflows */
static int readIntFromChar ( const char * * stringPtr ) {
static const char errorMsg [ ] = " error: numeric value overflows 32-bit int " ;
int sign = 1 ;
unsigned result ;
if ( * * stringPtr = = ' - ' ) {
( * stringPtr ) + + ;
sign = - 1 ;
}
if ( readU32FromCharChecked ( stringPtr , & result ) ) { errorOut ( errorMsg ) ; }
return ( int ) result * sign ;
}
2020-02-20 11:29:58 -08:00
/*! readSizeTFromCharChecked() :
* @ return 0 if success , and store the result in * value .
* allows and interprets K , KB , KiB , M , MB and MiB suffix .
* Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
* @ return 1 if an overflow error occurs */
static int readSizeTFromCharChecked ( const char * * stringPtr , size_t * value )
{
size_t result = 0 ;
while ( ( * * stringPtr > = ' 0 ' ) & & ( * * stringPtr < = ' 9 ' ) ) {
size_t const max = ( ( size_t ) ( - 1 ) ) / 10 ;
size_t last = result ;
if ( result > max ) return 1 ; /* overflow error */
result * = 10 ;
result + = ( size_t ) ( * * stringPtr - ' 0 ' ) ;
if ( result < last ) return 1 ; /* overflow error */
( * stringPtr ) + + ;
}
if ( ( * * stringPtr = = ' K ' ) | | ( * * stringPtr = = ' M ' ) ) {
size_t const maxK = ( ( size_t ) ( - 1 ) ) > > 10 ;
if ( result > maxK ) return 1 ; /* overflow error */
result < < = 10 ;
if ( * * stringPtr = = ' M ' ) {
if ( result > maxK ) return 1 ; /* overflow error */
result < < = 10 ;
}
( * stringPtr ) + + ; /* skip `K` or `M` */
if ( * * stringPtr = = ' i ' ) ( * stringPtr ) + + ;
if ( * * stringPtr = = ' B ' ) ( * stringPtr ) + + ;
}
* value = result ;
return 0 ;
}
/*! readSizeTFromChar() :
* @ return : size_t value read from input in ` char ` format .
* allows and interprets K , KB , KiB , M , MB and MiB suffix .
* Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
* Note : function will exit ( ) program if digit sequence overflows */
static size_t readSizeTFromChar ( const char * * stringPtr ) {
static const char errorMsg [ ] = " error: numeric value overflows size_t " ;
size_t result ;
if ( readSizeTFromCharChecked ( stringPtr , & result ) ) { errorOut ( errorMsg ) ; }
return result ;
}
2016-12-02 15:18:57 -08:00
/** longCommandWArg() :
2017-01-30 13:07:24 -08:00
* check if * stringPtr is the same as longCommand .
2016-12-02 15:18:57 -08:00
* If yes , @ return 1 and advances * stringPtr to the position which immediately follows longCommand .
2018-03-11 19:56:48 -07:00
* @ return 0 and doesn ' t modify * stringPtr otherwise .
2016-12-02 15:18:57 -08:00
*/
2019-10-17 15:27:25 -07:00
static int longCommandWArg ( const char * * stringPtr , const char * longCommand )
2016-10-14 14:41:17 -07:00
{
size_t const comSize = strlen ( longCommand ) ;
2016-12-02 15:18:57 -08:00
int const result = ! strncmp ( * stringPtr , longCommand , comSize ) ;
2016-10-14 14:41:17 -07:00
if ( result ) * stringPtr + = comSize ;
return result ;
}
2016-12-13 03:18:07 -08:00
2016-12-31 21:08:24 -08:00
# ifndef ZSTD_NODICT
2019-07-18 11:44:59 -07:00
static const unsigned kDefaultRegression = 1 ;
2016-12-31 21:08:24 -08:00
/**
* parseCoverParameters ( ) :
2017-05-01 23:40:20 -07:00
* reads cover parameters from * stringPtr ( e . g . " --train-cover=k=48,d=8,steps=32 " ) into * params
2016-12-31 21:08:24 -08:00
* @ return 1 means that cover parameters were correct
* @ return 0 in case of malformed parameters
*/
2017-06-26 21:07:14 -07:00
static unsigned parseCoverParameters ( const char * stringPtr , ZDICT_cover_params_t * params )
2016-12-31 21:08:24 -08:00
{
memset ( params , 0 , sizeof ( * params ) ) ;
for ( ; ; ) {
2017-01-02 12:40:43 -08:00
if ( longCommandWArg ( & stringPtr , " k= " ) ) { params - > k = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2016-12-31 21:08:24 -08:00
if ( longCommandWArg ( & stringPtr , " d= " ) ) { params - > d = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-01-02 12:40:43 -08:00
if ( longCommandWArg ( & stringPtr , " steps= " ) ) { params - > steps = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-06-29 17:54:41 -07:00
if ( longCommandWArg ( & stringPtr , " split= " ) ) {
2018-07-03 17:53:27 -07:00
unsigned splitPercentage = readU32FromChar ( & stringPtr ) ;
2018-06-29 17:54:41 -07:00
params - > splitPoint = ( double ) splitPercentage / 100.0 ;
if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ;
}
2019-06-27 16:26:57 -07:00
if ( longCommandWArg ( & stringPtr , " shrink " ) ) {
params - > shrinkDictMaxRegression = kDefaultRegression ;
params - > shrinkDict = 1 ;
if ( stringPtr [ 0 ] = = ' = ' ) {
stringPtr + + ;
params - > shrinkDictMaxRegression = readU32FromChar ( & stringPtr ) ;
}
if ( stringPtr [ 0 ] = = ' , ' ) {
stringPtr + + ;
continue ;
}
else break ;
}
2016-12-31 21:08:24 -08:00
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
2019-06-27 16:26:57 -07:00
DISPLAYLEVEL ( 4 , " cover: k=%u \n d=%u \n steps=%u \n split=%u \n shrink%u \n " , params - > k , params - > d , params - > steps , ( unsigned ) ( params - > splitPoint * 100 ) , params - > shrinkDictMaxRegression ) ;
2016-12-31 21:08:24 -08:00
return 1 ;
}
2017-05-01 23:40:20 -07:00
2018-08-23 12:06:20 -07:00
/**
* parseFastCoverParameters ( ) :
* reads fastcover parameters from * stringPtr ( e . g . " --train-fastcover=k=48,d=8,f=20,steps=32,accel=2 " ) into * params
* @ return 1 means that fastcover parameters were correct
* @ return 0 in case of malformed parameters
*/
static unsigned parseFastCoverParameters ( const char * stringPtr , ZDICT_fastCover_params_t * params )
{
memset ( params , 0 , sizeof ( * params ) ) ;
for ( ; ; ) {
if ( longCommandWArg ( & stringPtr , " k= " ) ) { params - > k = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " d= " ) ) { params - > d = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " f= " ) ) { params - > f = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " steps= " ) ) { params - > steps = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " accel= " ) ) { params - > accel = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " split= " ) ) {
unsigned splitPercentage = readU32FromChar ( & stringPtr ) ;
params - > splitPoint = ( double ) splitPercentage / 100.0 ;
if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ;
}
2019-06-27 16:26:57 -07:00
if ( longCommandWArg ( & stringPtr , " shrink " ) ) {
params - > shrinkDictMaxRegression = kDefaultRegression ;
params - > shrinkDict = 1 ;
if ( stringPtr [ 0 ] = = ' = ' ) {
stringPtr + + ;
params - > shrinkDictMaxRegression = readU32FromChar ( & stringPtr ) ;
}
if ( stringPtr [ 0 ] = = ' , ' ) {
stringPtr + + ;
continue ;
}
else break ;
}
2018-08-23 12:06:20 -07:00
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
2019-06-27 16:26:57 -07:00
DISPLAYLEVEL ( 4 , " cover: k=%u \n d=%u \n f=%u \n steps=%u \n split=%u \n accel=%u \n shrink=%u \n " , params - > k , params - > d , params - > f , params - > steps , ( unsigned ) ( params - > splitPoint * 100 ) , params - > accel , params - > shrinkDictMaxRegression ) ;
2018-08-23 12:06:20 -07:00
return 1 ;
}
2017-05-01 23:40:20 -07:00
/**
* parseLegacyParameters ( ) :
2019-04-12 11:18:11 -07:00
* reads legacy dictionary builder parameters from * stringPtr ( e . g . " --train-legacy=selectivity=8 " ) into * selectivity
2017-05-01 23:40:20 -07:00
* @ return 1 means that legacy dictionary builder parameters were correct
* @ return 0 in case of malformed parameters
*/
static unsigned parseLegacyParameters ( const char * stringPtr , unsigned * selectivity )
{
if ( ! longCommandWArg ( & stringPtr , " s= " ) & & ! longCommandWArg ( & stringPtr , " selectivity= " ) ) { return 0 ; }
* selectivity = readU32FromChar ( & stringPtr ) ;
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
DISPLAYLEVEL ( 4 , " legacy: selectivity=%u \n " , * selectivity ) ;
return 1 ;
}
2017-06-26 21:07:14 -07:00
static ZDICT_cover_params_t defaultCoverParams ( void )
2017-05-01 23:40:20 -07:00
{
2017-06-26 21:07:14 -07:00
ZDICT_cover_params_t params ;
2017-05-01 23:40:20 -07:00
memset ( & params , 0 , sizeof ( params ) ) ;
params . d = 8 ;
params . steps = 4 ;
2018-08-23 12:06:20 -07:00
params . splitPoint = 1.0 ;
2019-06-27 16:26:57 -07:00
params . shrinkDict = 0 ;
params . shrinkDictMaxRegression = kDefaultRegression ;
2018-08-23 12:06:20 -07:00
return params ;
}
static ZDICT_fastCover_params_t defaultFastCoverParams ( void )
{
ZDICT_fastCover_params_t params ;
memset ( & params , 0 , sizeof ( params ) ) ;
params . d = 8 ;
2018-09-04 17:12:35 -07:00
params . f = 20 ;
2018-08-23 12:06:20 -07:00
params . steps = 4 ;
params . splitPoint = 0.75 ; /* different from default splitPoint of cover */
params . accel = DEFAULT_ACCEL ;
2019-06-27 16:26:57 -07:00
params . shrinkDict = 0 ;
params . shrinkDictMaxRegression = kDefaultRegression ;
2017-05-01 23:40:20 -07:00
return params ;
}
2016-12-31 21:08:24 -08:00
# endif
2017-01-30 13:07:24 -08:00
2018-09-24 18:16:08 -07:00
/** parseAdaptParameters() :
* reads adapt parameters from * stringPtr ( e . g . " --zstd=min=1,max=19) and store them into adaptMinPtr and adaptMaxPtr.
* Both adaptMinPtr and adaptMaxPtr must be already allocated and correctly initialized .
* There is no guarantee that any of these values will be updated .
* @ return 1 means that parsing was successful ,
* @ return 0 in case of malformed parameters
*/
static unsigned parseAdaptParameters ( const char * stringPtr , int * adaptMinPtr , int * adaptMaxPtr )
{
for ( ; ; ) {
2021-06-09 13:49:36 -07:00
if ( longCommandWArg ( & stringPtr , " min= " ) ) { * adaptMinPtr = readIntFromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " max= " ) ) { * adaptMaxPtr = readIntFromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-09-24 18:16:08 -07:00
DISPLAYLEVEL ( 4 , " invalid compression parameter \n " ) ;
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ; /* check the end of string */
if ( * adaptMinPtr > * adaptMaxPtr ) {
DISPLAYLEVEL ( 4 , " incoherent adaptation limits \n " ) ;
return 0 ;
}
return 1 ;
}
2016-12-13 03:18:07 -08:00
/** parseCompressionParameters() :
2018-11-20 14:56:07 -08:00
* reads compression parameters from * stringPtr ( e . g . " --zstd=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 " ) into * params
2016-12-13 03:18:07 -08:00
* @ return 1 means that compression parameters were correct
* @ return 0 in case of malformed parameters
*/
static unsigned parseCompressionParameters ( const char * stringPtr , ZSTD_compressionParameters * params )
{
for ( ; ; ) {
if ( longCommandWArg ( & stringPtr , " windowLog= " ) | | longCommandWArg ( & stringPtr , " wlog= " ) ) { params - > windowLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " chainLog= " ) | | longCommandWArg ( & stringPtr , " clog= " ) ) { params - > chainLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " hashLog= " ) | | longCommandWArg ( & stringPtr , " hlog= " ) ) { params - > hashLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " searchLog= " ) | | longCommandWArg ( & stringPtr , " slog= " ) ) { params - > searchLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-11-20 14:56:07 -08:00
if ( longCommandWArg ( & stringPtr , " minMatch= " ) | | longCommandWArg ( & stringPtr , " mml= " ) ) { params - > minMatch = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2016-12-13 03:18:07 -08:00
if ( longCommandWArg ( & stringPtr , " targetLength= " ) | | longCommandWArg ( & stringPtr , " tlen= " ) ) { params - > targetLength = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-06-20 14:11:49 -07:00
if ( longCommandWArg ( & stringPtr , " strategy= " ) | | longCommandWArg ( & stringPtr , " strat= " ) ) { params - > strategy = ( ZSTD_strategy ) ( readU32FromChar ( & stringPtr ) ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-01-30 13:07:24 -08:00
if ( longCommandWArg ( & stringPtr , " overlapLog= " ) | | longCommandWArg ( & stringPtr , " ovlog= " ) ) { g_overlapLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-11-20 14:56:07 -08:00
if ( longCommandWArg ( & stringPtr , " ldmHashLog= " ) | | longCommandWArg ( & stringPtr , " lhlog= " ) ) { g_ldmHashLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " ldmMinMatch= " ) | | longCommandWArg ( & stringPtr , " lmml= " ) ) { g_ldmMinMatch = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " ldmBucketSizeLog= " ) | | longCommandWArg ( & stringPtr , " lblog= " ) ) { g_ldmBucketSizeLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-11-21 14:36:57 -08:00
if ( longCommandWArg ( & stringPtr , " ldmHashRateLog= " ) | | longCommandWArg ( & stringPtr , " lhrlog= " ) ) { g_ldmHashRateLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-12-27 04:32:05 -08:00
DISPLAYLEVEL ( 4 , " invalid compression parameter \n " ) ;
2016-12-13 03:18:07 -08:00
return 0 ;
}
2017-12-27 04:32:05 -08:00
DISPLAYLEVEL ( 4 , " windowLog=%d, chainLog=%d, hashLog=%d, searchLog=%d \n " , params - > windowLog , params - > chainLog , params - > hashLog , params - > searchLog ) ;
2018-11-20 14:56:07 -08:00
DISPLAYLEVEL ( 4 , " minMatch=%d, targetLength=%d, strategy=%d \n " , params - > minMatch , params - > targetLength , params - > strategy ) ;
2016-12-13 03:18:07 -08:00
if ( stringPtr [ 0 ] ! = 0 ) return 0 ; /* check the end of string */
return 1 ;
}
2017-08-19 13:33:50 -07:00
static void printVersion ( void )
{
2020-06-08 05:06:37 -07:00
if ( g_displayLevel < DISPLAY_LEVEL_DEFAULT ) {
DISPLAYOUT ( " %s \n " , ZSTD_VERSION_STRING ) ;
return ;
}
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( WELCOME_MESSAGE ) ;
if ( g_displayLevel > = 3 ) {
2017-08-19 13:33:50 -07:00
/* format support */
2019-12-02 16:08:08 -08:00
DISPLAYOUT ( " *** supports: zstd " ) ;
# if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>0) && (ZSTD_LEGACY_SUPPORT<8)
DISPLAYOUT ( " , zstd legacy v0.%d+ " , ZSTD_LEGACY_SUPPORT ) ;
# endif
# ifdef ZSTD_GZCOMPRESS
DISPLAYOUT ( " , gzip " ) ;
# endif
# ifdef ZSTD_LZ4COMPRESS
DISPLAYOUT ( " , lz4 " ) ;
# endif
# ifdef ZSTD_LZMACOMPRESS
DISPLAYOUT ( " , lzma, xz " ) ;
# endif
DISPLAYOUT ( " \n " ) ;
if ( g_displayLevel > = 4 ) {
/* posix support */
# ifdef _POSIX_C_SOURCE
DISPLAYOUT ( " _POSIX_C_SOURCE defined: %ldL \n " , ( long ) _POSIX_C_SOURCE ) ;
# endif
# ifdef _POSIX_VERSION
DISPLAYOUT ( " _POSIX_VERSION defined: %ldL \n " , ( long ) _POSIX_VERSION ) ;
# endif
# ifdef PLATFORM_POSIX_VERSION
DISPLAYOUT ( " PLATFORM_POSIX_VERSION defined: %ldL \n " , ( long ) PLATFORM_POSIX_VERSION ) ;
# endif
} }
2017-08-19 13:33:50 -07:00
}
2016-12-13 03:18:07 -08:00
2021-11-05 12:48:13 -07:00
# define ZSTD_NB_STRATEGIES 9
static const char * ZSTD_strategyMap [ ZSTD_NB_STRATEGIES + 1 ] = { " " , " ZSTD_fast " ,
" ZSTD_dfast " , " ZSTD_greedy " , " ZSTD_lazy " , " ZSTD_lazy2 " , " ZSTD_btlazy2 " ,
" ZSTD_btopt " , " ZSTD_btultra " , " ZSTD_btultra2 " } ;
2021-11-11 12:14:56 -08:00
# ifndef ZSTD_NOCOMPRESS
2021-11-05 12:48:13 -07:00
static void printDefaultCParams ( const char * filename , const char * dictFileName , int cLevel ) {
unsigned long long fileSize = UTIL_getFileSize ( filename ) ;
const size_t dictSize = dictFileName ! = NULL ? ( size_t ) UTIL_getFileSize ( dictFileName ) : 0 ;
const ZSTD_compressionParameters cParams = ZSTD_getCParams ( cLevel , fileSize , dictSize ) ;
if ( fileSize ! = UTIL_FILESIZE_UNKNOWN ) DISPLAY ( " %s (%u bytes) \n " , filename , ( unsigned ) fileSize ) ;
else DISPLAY ( " %s (src size unknown) \ n " , filename) ;
DISPLAY ( " - windowLog : %u \n " , cParams . windowLog ) ;
DISPLAY ( " - chainLog : %u \n " , cParams . chainLog ) ;
DISPLAY ( " - hashLog : %u \n " , cParams . hashLog ) ;
DISPLAY ( " - searchLog : %u \n " , cParams . searchLog ) ;
DISPLAY ( " - minMatch : %u \n " , cParams . minMatch ) ;
DISPLAY ( " - targetLength : %u \n " , cParams . targetLength ) ;
assert ( cParams . strategy < ZSTD_NB_STRATEGIES + 1 ) ;
DISPLAY ( " - strategy : %s (%u) \n " , ZSTD_strategyMap [ ( int ) cParams . strategy ] , ( unsigned ) cParams . strategy ) ;
}
static void printActualCParams ( const char * filename , const char * dictFileName , int cLevel , const ZSTD_compressionParameters * cParams ) {
unsigned long long fileSize = UTIL_getFileSize ( filename ) ;
const size_t dictSize = dictFileName ! = NULL ? ( size_t ) UTIL_getFileSize ( dictFileName ) : 0 ;
ZSTD_compressionParameters actualCParams = ZSTD_getCParams ( cLevel , fileSize , dictSize ) ;
assert ( g_displayLevel > = 4 ) ;
actualCParams . windowLog = cParams - > windowLog = = 0 ? actualCParams . windowLog : cParams - > windowLog ;
actualCParams . chainLog = cParams - > chainLog = = 0 ? actualCParams . chainLog : cParams - > chainLog ;
actualCParams . hashLog = cParams - > hashLog = = 0 ? actualCParams . hashLog : cParams - > hashLog ;
actualCParams . searchLog = cParams - > searchLog = = 0 ? actualCParams . searchLog : cParams - > searchLog ;
actualCParams . minMatch = cParams - > minMatch = = 0 ? actualCParams . minMatch : cParams - > minMatch ;
actualCParams . targetLength = cParams - > targetLength = = 0 ? actualCParams . targetLength : cParams - > targetLength ;
actualCParams . strategy = cParams - > strategy = = 0 ? actualCParams . strategy : cParams - > strategy ;
DISPLAY ( " --zstd=wlog=%d,clog=%d,hlog=%d,slog=%d,mml=%d,tlen=%d,strat=%d \n " ,
actualCParams . windowLog , actualCParams . chainLog , actualCParams . hashLog , actualCParams . searchLog ,
actualCParams . minMatch , actualCParams . targetLength , actualCParams . strategy ) ;
}
2021-11-11 12:14:56 -08:00
# endif
2018-12-19 13:26:27 -08:00
/* Environment variables for parameter setting */
# define ENV_CLEVEL "ZSTD_CLEVEL"
2020-09-09 09:35:40 -07:00
# define ENV_NBTHREADS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */
2018-12-19 13:26:27 -08:00
2019-12-02 16:08:08 -08:00
/* pick up environment variable */
2018-12-19 17:56:45 -08:00
static int init_cLevel ( void ) {
2018-12-19 16:45:42 -08:00
const char * const env = getenv ( ENV_CLEVEL ) ;
2019-12-02 14:28:18 -08:00
if ( env ! = NULL ) {
const char * ptr = env ;
2018-12-19 13:26:27 -08:00
int sign = 1 ;
2018-12-19 16:45:42 -08:00
if ( * ptr = = ' - ' ) {
2018-12-19 13:26:27 -08:00
sign = - 1 ;
2018-12-19 16:45:42 -08:00
ptr + + ;
} else if ( * ptr = = ' + ' ) {
ptr + + ;
}
if ( ( * ptr > = ' 0 ' ) & & ( * ptr < = ' 9 ' ) ) {
unsigned absLevel ;
2019-04-10 10:03:06 -07:00
if ( readU32FromCharChecked ( & ptr , & absLevel ) ) {
2019-12-02 14:28:18 -08:00
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: numeric value too large \n " , ENV_CLEVEL , env ) ;
2018-12-19 16:45:42 -08:00
return ZSTDCLI_CLEVEL_DEFAULT ;
} else if ( * ptr = = 0 ) {
2019-10-17 15:27:25 -07:00
return sign * ( int ) absLevel ;
2019-12-02 14:28:18 -08:00
} }
2018-12-19 13:26:27 -08:00
2019-12-02 14:28:18 -08:00
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: not a valid integer value \n " , ENV_CLEVEL , env ) ;
2018-12-19 13:26:27 -08:00
}
return ZSTDCLI_CLEVEL_DEFAULT ;
}
2020-09-08 06:26:16 -07:00
# ifdef ZSTD_MULTITHREAD
2020-09-09 09:35:40 -07:00
static unsigned init_nbThreads ( void ) {
const char * const env = getenv ( ENV_NBTHREADS ) ;
2020-08-25 15:49:52 -07:00
if ( env ! = NULL ) {
const char * ptr = env ;
if ( ( * ptr > = ' 0 ' ) & & ( * ptr < = ' 9 ' ) ) {
2020-09-09 09:35:40 -07:00
unsigned nbThreads ;
if ( readU32FromCharChecked ( & ptr , & nbThreads ) ) {
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: numeric value too large \n " , ENV_NBTHREADS , env ) ;
return ZSTDCLI_NBTHREADS_DEFAULT ;
2020-08-25 15:49:52 -07:00
} else if ( * ptr = = 0 ) {
2020-09-09 09:35:40 -07:00
return nbThreads ;
2020-08-25 15:49:52 -07:00
}
}
2020-09-09 09:35:40 -07:00
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: not a valid unsigned value \n " , ENV_NBTHREADS , env ) ;
2020-08-25 15:49:52 -07:00
}
2020-09-09 09:35:40 -07:00
return ZSTDCLI_NBTHREADS_DEFAULT ;
2020-08-25 15:49:52 -07:00
}
2020-09-08 06:26:16 -07:00
# endif
2020-08-25 15:49:52 -07:00
2020-07-20 17:41:32 -07:00
# define NEXT_FIELD(ptr) { \
if ( * argument = = ' = ' ) { \
ptr = + + argument ; \
argument + = strlen ( ptr ) ; \
} else { \
argNb + + ; \
if ( argNb > = argCount ) { \
DISPLAY ( " error: missing command argument \n " ) ; \
CLEAN_RETURN ( 1 ) ; \
} \
ptr = argv [ argNb ] ; \
assert ( ptr ! = NULL ) ; \
if ( ptr [ 0 ] = = ' - ' ) { \
DISPLAY ( " error: command cannot be separated from its argument by another command \n " ) ; \
CLEAN_RETURN ( 1 ) ; \
} } }
# define NEXT_UINT32(val32) { \
const char * __nb ; \
NEXT_FIELD ( __nb ) ; \
val32 = readU32FromChar ( & __nb ) ; \
2020-07-17 12:46:36 -07:00
}
2020-01-31 10:47:17 -08:00
2017-06-05 14:45:31 -07:00
typedef enum { zom_compress , zom_decompress , zom_test , zom_bench , zom_train , zom_list } zstd_operation_mode ;
2016-05-28 20:16:05 -07:00
# define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
2018-09-24 18:16:08 -07:00
# ifdef ZSTD_NOCOMPRESS
/* symbols from compression library are not defined and should not be invoked */
2019-12-02 14:28:18 -08:00
# define MINCLEVEL -99
2018-09-24 18:16:08 -07:00
# define MAXCLEVEL 22
# else
# define MINCLEVEL ZSTD_minCLevel()
# define MAXCLEVEL ZSTD_maxCLevel()
# endif
2021-07-14 09:55:47 -07:00
int main ( int argCount , const char * argv [ ] )
2016-05-28 20:16:05 -07:00
{
int argNb ,
2018-02-13 14:56:35 -08:00
followLinks = 0 ,
2021-05-04 13:24:46 -07:00
allowBlockDevices = 0 ,
2021-01-11 14:53:20 -08:00
forceStdin = 0 ,
2018-02-13 14:56:35 -08:00
forceStdout = 0 ,
2020-10-07 10:47:38 -07:00
hasStdout = 0 ,
2018-02-09 15:53:27 -08:00
ldmFlag = 0 ,
2018-02-13 14:56:35 -08:00
main_pause = 0 ,
nbWorkers = 0 ,
2018-08-11 20:48:06 -07:00
adapt = 0 ,
2020-11-02 17:52:29 -08:00
useRowMatchFinder = 0 ,
2018-09-24 18:16:08 -07:00
adaptMin = MINCLEVEL ,
adaptMax = MAXCLEVEL ,
2018-11-12 19:59:42 -08:00
rsyncable = 0 ,
2018-02-13 14:56:35 -08:00
nextArgumentsAreFiles = 0 ,
operationResult = 0 ,
2017-11-17 00:22:55 -08:00
separateFiles = 0 ,
2018-02-09 15:53:27 -08:00
setRealTimePrio = 0 ,
2018-02-13 14:56:35 -08:00
singleThread = 0 ,
2021-06-16 06:38:43 -07:00
# ifdef ZSTD_MULTITHREAD
defaultLogicalCores = 0 ,
# endif
2020-01-30 14:12:03 -08:00
showDefaultCParams = 0 ,
2020-03-09 11:07:29 -07:00
ultra = 0 ,
2020-03-09 12:12:52 -07:00
contentSize = 1 ;
2018-06-19 10:58:22 -07:00
double compressibility = 0.5 ;
2017-01-19 16:59:56 -08:00
unsigned bench_nbSeconds = 3 ; /* would be better if this value was synchronized from bench */
size_t blockSize = 0 ;
2019-01-22 17:31:13 -08:00
FIO_prefs_t * const prefs = FIO_createPreferences ( ) ;
2020-08-28 08:01:04 -07:00
FIO_ctx_t * const fCtx = FIO_createContext ( ) ;
2016-10-28 13:58:31 -07:00
zstd_operation_mode operation = zom_compress ;
2016-12-13 03:18:07 -08:00
ZSTD_compressionParameters compressionParams ;
2019-12-02 16:08:08 -08:00
int cLevel = init_cLevel ( ) ;
2019-12-02 14:28:18 -08:00
int cLevelLast = MINCLEVEL - 1 ; /* lower than minimum */
2016-05-28 20:16:05 -07:00
unsigned recursive = 0 ;
2016-10-14 13:13:13 -07:00
unsigned memLimit = 0 ;
2019-11-05 17:02:43 -08:00
FileNamesTable * filenames = UTIL_allocateFileNamesTable ( ( size_t ) argCount ) ; /* argCount >= 1 */
FileNamesTable * file_of_names = UTIL_allocateFileNamesTable ( ( size_t ) argCount ) ; /* argCount >= 1 */
2016-05-28 20:16:05 -07:00
const char * programName = argv [ 0 ] ;
const char * outFileName = NULL ;
2019-09-05 16:03:35 -07:00
const char * outDirName = NULL ;
2020-06-19 19:35:51 -07:00
const char * outMirroredDirName = NULL ;
2016-05-28 20:16:05 -07:00
const char * dictFileName = NULL ;
2020-01-10 14:25:24 -08:00
const char * patchFromDictFileName = NULL ;
2017-02-08 08:37:14 -08:00
const char * suffix = ZSTD_EXTENSION ;
2016-05-28 20:16:05 -07:00
unsigned maxDictSize = g_defaultMaxDictSize ;
2016-05-30 12:18:52 -07:00
unsigned dictID = 0 ;
2019-08-15 23:57:55 -07:00
size_t streamSrcSize = 0 ;
2019-06-24 13:40:52 -07:00
size_t targetCBlockSize = 0 ;
2019-08-19 08:52:08 -07:00
size_t srcSizeHint = 0 ;
2016-07-27 06:09:11 -07:00
int dictCLevel = g_defaultDictCLevel ;
2016-05-28 20:16:05 -07:00
unsigned dictSelect = g_defaultSelectivityLevel ;
2016-12-31 21:08:24 -08:00
# ifndef ZSTD_NODICT
2017-06-26 21:07:14 -07:00
ZDICT_cover_params_t coverParams = defaultCoverParams ( ) ;
2018-08-23 12:06:20 -07:00
ZDICT_fastCover_params_t fastCoverParams = defaultFastCoverParams ( ) ;
dictType dict = fastCover ;
2016-12-31 21:08:24 -08:00
# endif
2018-08-03 07:54:29 -07:00
# ifndef ZSTD_NOBENCH
BMK_advancedParams_t benchParams = BMK_initAdvancedParams ( ) ;
# endif
2021-09-20 06:04:07 -07:00
ZSTD_paramSwitch_e literalCompressionMode = ZSTD_ps_auto ;
2016-05-28 20:16:05 -07:00
2017-10-01 12:10:26 -07:00
2016-05-28 20:16:05 -07:00
/* init */
2021-01-07 10:37:27 -08:00
checkLibVersion ( ) ;
2016-06-04 16:05:01 -07:00
( void ) recursive ; ( void ) cLevelLast ; /* not used when ZSTD_NOBENCH set */
2020-01-10 14:25:24 -08:00
( void ) memLimit ;
2019-12-02 14:28:18 -08:00
assert ( argCount > = 1 ) ;
2019-11-05 17:02:43 -08:00
if ( ( filenames = = NULL ) | | ( file_of_names = = NULL ) ) { DISPLAY ( " zstd: allocation error \n " ) ; exit ( 1 ) ; }
2017-03-24 17:06:09 -07:00
programName = lastNameFromPath ( programName ) ;
2018-02-13 14:56:35 -08:00
# ifdef ZSTD_MULTITHREAD
2020-09-09 09:35:40 -07:00
nbWorkers = init_nbThreads ( ) ;
2018-02-13 14:56:35 -08:00
# endif
2016-05-28 20:16:05 -07:00
/* preset behaviors */
2018-06-29 17:10:56 -07:00
if ( exeNameMatch ( programName , ZSTD_ZSTDMT ) ) nbWorkers = 0 , singleThread = 0 ;
2017-03-24 17:06:09 -07:00
if ( exeNameMatch ( programName , ZSTD_UNZSTD ) ) operation = zom_decompress ;
2019-04-27 16:06:29 -07:00
if ( exeNameMatch ( programName , ZSTD_CAT ) ) { operation = zom_decompress ; FIO_overwriteMode ( prefs ) ; forceStdout = 1 ; followLinks = 1 ; outFileName = stdoutmark ; g_displayLevel = 1 ; } /* supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_ZCAT ) ) { operation = zom_decompress ; FIO_overwriteMode ( prefs ) ; forceStdout = 1 ; followLinks = 1 ; outFileName = stdoutmark ; g_displayLevel = 1 ; } /* behave like zcat, also supports multiple formats */
2019-01-22 17:31:13 -08:00
if ( exeNameMatch ( programName , ZSTD_GZ ) ) { suffix = GZ_EXTENSION ; FIO_setCompressionType ( prefs , FIO_gzipCompression ) ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like gzip */
if ( exeNameMatch ( programName , ZSTD_GUNZIP ) ) { operation = zom_decompress ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like gunzip, also supports multiple formats */
2019-04-27 16:06:29 -07:00
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 */
2019-01-22 17:31:13 -08:00
if ( exeNameMatch ( programName , ZSTD_LZMA ) ) { suffix = LZMA_EXTENSION ; FIO_setCompressionType ( prefs , FIO_lzmaCompression ) ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like lzma */
if ( exeNameMatch ( programName , ZSTD_UNLZMA ) ) { operation = zom_decompress ; FIO_setCompressionType ( prefs , FIO_lzmaCompression ) ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like unlzma, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_XZ ) ) { suffix = XZ_EXTENSION ; FIO_setCompressionType ( prefs , FIO_xzCompression ) ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like xz */
if ( exeNameMatch ( programName , ZSTD_UNXZ ) ) { operation = zom_decompress ; FIO_setCompressionType ( prefs , FIO_xzCompression ) ; FIO_setRemoveSrcFile ( prefs , 1 ) ; } /* behave like unxz, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_LZ4 ) ) { suffix = LZ4_EXTENSION ; FIO_setCompressionType ( prefs , FIO_lz4Compression ) ; } /* behave like lz4 */
if ( exeNameMatch ( programName , ZSTD_UNLZ4 ) ) { operation = zom_decompress ; FIO_setCompressionType ( prefs , FIO_lz4Compression ) ; } /* behave like unlz4, also supports multiple formats */
2016-12-13 03:18:07 -08:00
memset ( & compressionParams , 0 , sizeof ( compressionParams ) ) ;
2016-05-28 20:16:05 -07:00
2018-09-06 18:46:52 -07:00
/* init crash handler */
2018-09-11 11:56:50 -07:00
FIO_addAbortHandler ( ) ;
2018-09-06 18:46:52 -07:00
2016-05-28 20:16:05 -07:00
/* command switches */
2016-10-14 14:07:11 -07:00
for ( argNb = 1 ; argNb < argCount ; argNb + + ) {
2016-05-28 20:16:05 -07:00
const char * argument = argv [ argNb ] ;
2019-11-05 17:02:43 -08:00
if ( ! argument ) continue ; /* Protection if argument empty */
if ( nextArgumentsAreFiles ) {
UTIL_refFilename ( filenames , argument ) ;
continue ;
}
/* "-" means stdin/stdout */
if ( ! strcmp ( argument , " - " ) ) {
UTIL_refFilename ( filenames , stdinmark ) ;
continue ;
}
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Decode commands (note : aggregated commands are allowed) */
if ( argument [ 0 ] = = ' - ' ) {
if ( argument [ 1 ] = = ' - ' ) {
/* long commands (--long-word) */
if ( ! strcmp ( argument , " -- " ) ) { nextArgumentsAreFiles = 1 ; continue ; } /* only file names allowed from now on */
if ( ! strcmp ( argument , " --list " ) ) { operation = zom_list ; continue ; }
if ( ! strcmp ( argument , " --compress " ) ) { operation = zom_compress ; continue ; }
if ( ! strcmp ( argument , " --decompress " ) ) { operation = zom_decompress ; continue ; }
if ( ! strcmp ( argument , " --uncompress " ) ) { operation = zom_decompress ; continue ; }
2021-05-04 13:24:46 -07:00
if ( ! strcmp ( argument , " --force " ) ) { FIO_overwriteMode ( prefs ) ; forceStdin = 1 ; forceStdout = 1 ; followLinks = 1 ; allowBlockDevices = 1 ; continue ; }
2019-12-02 16:08:08 -08:00
if ( ! strcmp ( argument , " --version " ) ) { printVersion ( ) ; CLEAN_RETURN ( 0 ) ; }
if ( ! strcmp ( argument , " --help " ) ) { usage_advanced ( programName ) ; CLEAN_RETURN ( 0 ) ; }
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --verbose " ) ) { g_displayLevel + + ; continue ; }
if ( ! strcmp ( argument , " --quiet " ) ) { g_displayLevel - - ; continue ; }
if ( ! strcmp ( argument , " --stdout " ) ) { forceStdout = 1 ; outFileName = stdoutmark ; g_displayLevel - = ( g_displayLevel = = 2 ) ; continue ; }
if ( ! strcmp ( argument , " --ultra " ) ) { ultra = 1 ; continue ; }
if ( ! strcmp ( argument , " --check " ) ) { FIO_setChecksumFlag ( prefs , 2 ) ; continue ; }
if ( ! strcmp ( argument , " --no-check " ) ) { FIO_setChecksumFlag ( prefs , 0 ) ; continue ; }
if ( ! strcmp ( argument , " --sparse " ) ) { FIO_setSparseWrite ( prefs , 2 ) ; continue ; }
if ( ! strcmp ( argument , " --no-sparse " ) ) { FIO_setSparseWrite ( prefs , 0 ) ; continue ; }
if ( ! strcmp ( argument , " --test " ) ) { operation = zom_test ; continue ; }
if ( ! strcmp ( argument , " --train " ) ) { operation = zom_train ; if ( outFileName = = NULL ) outFileName = g_defaultDictName ; continue ; }
if ( ! strcmp ( argument , " --no-dictID " ) ) { FIO_setDictIDFlag ( prefs , 0 ) ; continue ; }
if ( ! strcmp ( argument , " --keep " ) ) { FIO_setRemoveSrcFile ( prefs , 0 ) ; continue ; }
if ( ! strcmp ( argument , " --rm " ) ) { FIO_setRemoveSrcFile ( prefs , 1 ) ; continue ; }
if ( ! strcmp ( argument , " --priority=rt " ) ) { setRealTimePrio = 1 ; continue ; }
2020-01-30 14:12:03 -08:00
if ( ! strcmp ( argument , " --show-default-cparams " ) ) { showDefaultCParams = 1 ; continue ; }
2020-03-09 12:19:05 -07:00
if ( ! strcmp ( argument , " --content-size " ) ) { contentSize = 1 ; continue ; }
2020-03-09 12:12:52 -07:00
if ( ! strcmp ( argument , " --no-content-size " ) ) { contentSize = 0 ; continue ; }
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --adapt " ) ) { adapt = 1 ; continue ; }
2020-11-02 17:52:29 -08:00
if ( ! strcmp ( argument , " --no-row-match-finder " ) ) { useRowMatchFinder = 1 ; continue ; }
if ( ! strcmp ( argument , " --row-match-finder " ) ) { useRowMatchFinder = 2 ; continue ; }
2019-12-02 16:08:08 -08:00
if ( longCommandWArg ( & argument , " --adapt= " ) ) { adapt = 1 ; if ( ! parseAdaptParameters ( argument , & adaptMin , & adaptMax ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; } continue ; }
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --single-thread " ) ) { nbWorkers = 0 ; singleThread = 1 ; continue ; }
if ( ! strcmp ( argument , " --format=zstd " ) ) { suffix = ZSTD_EXTENSION ; FIO_setCompressionType ( prefs , FIO_zstdCompression ) ; continue ; }
2017-03-01 16:49:20 -08:00
# ifdef ZSTD_GZCOMPRESS
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --format=gzip " ) ) { suffix = GZ_EXTENSION ; FIO_setCompressionType ( prefs , FIO_gzipCompression ) ; continue ; }
2017-03-01 16:49:20 -08:00
# endif
2017-03-13 18:11:07 -07:00
# ifdef ZSTD_LZMACOMPRESS
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --format=lzma " ) ) { suffix = LZMA_EXTENSION ; FIO_setCompressionType ( prefs , FIO_lzmaCompression ) ; continue ; }
if ( ! strcmp ( argument , " --format=xz " ) ) { suffix = XZ_EXTENSION ; FIO_setCompressionType ( prefs , FIO_xzCompression ) ; continue ; }
2017-03-13 18:11:07 -07:00
# endif
2017-04-24 16:48:25 -07:00
# ifdef ZSTD_LZ4COMPRESS
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --format=lz4 " ) ) { suffix = LZ4_EXTENSION ; FIO_setCompressionType ( prefs , FIO_lz4Compression ) ; continue ; }
2017-04-24 16:48:25 -07:00
# endif
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --rsyncable " ) ) { rsyncable = 1 ; continue ; }
2021-09-20 06:04:07 -07:00
if ( ! strcmp ( argument , " --compress-literals " ) ) { literalCompressionMode = ZSTD_ps_enable ; continue ; }
if ( ! strcmp ( argument , " --no-compress-literals " ) ) { literalCompressionMode = ZSTD_ps_disable ; continue ; }
2021-05-06 11:50:28 -07:00
if ( ! strcmp ( argument , " --no-progress " ) ) { FIO_setProgressSetting ( FIO_ps_never ) ; continue ; }
if ( ! strcmp ( argument , " --progress " ) ) { FIO_setProgressSetting ( FIO_ps_always ) ; continue ; }
2019-11-05 17:02:43 -08:00
if ( ! strcmp ( argument , " --exclude-compressed " ) ) { FIO_setExcludeCompressedFile ( prefs , 1 ) ; continue ; }
2020-07-20 17:41:32 -07:00
2019-11-05 17:02:43 -08:00
/* long commands with arguments */
2017-03-01 16:49:20 -08:00
# ifndef ZSTD_NODICT
2019-11-05 17:02:43 -08:00
if ( longCommandWArg ( & argument , " --train-cover " ) ) {
operation = zom_train ;
if ( outFileName = = NULL )
outFileName = g_defaultDictName ;
dict = cover ;
/* Allow optional arguments following an = */
if ( * argument = = 0 ) { memset ( & coverParams , 0 , sizeof ( coverParams ) ) ; }
2019-12-02 16:08:08 -08:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseCoverParameters ( argument , & coverParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-05 17:02:43 -08:00
continue ;
}
if ( longCommandWArg ( & argument , " --train-fastcover " ) ) {
operation = zom_train ;
if ( outFileName = = NULL )
outFileName = g_defaultDictName ;
dict = fastCover ;
/* Allow optional arguments following an = */
if ( * argument = = 0 ) { memset ( & fastCoverParams , 0 , sizeof ( fastCoverParams ) ) ; }
2019-12-02 16:08:08 -08:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseFastCoverParameters ( argument , & fastCoverParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-05 17:02:43 -08:00
continue ;
}
if ( longCommandWArg ( & argument , " --train-legacy " ) ) {
operation = zom_train ;
if ( outFileName = = NULL )
outFileName = g_defaultDictName ;
dict = legacy ;
/* Allow optional arguments following an = */
if ( * argument = = 0 ) { continue ; }
2019-12-02 16:08:08 -08:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseLegacyParameters ( argument , & dictSelect ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-05 17:02:43 -08:00
continue ;
}
2016-12-31 21:08:24 -08:00
# endif
2020-07-20 17:41:32 -07:00
if ( longCommandWArg ( & argument , " --threads " ) ) { NEXT_UINT32 ( nbWorkers ) ; continue ; }
if ( longCommandWArg ( & argument , " --memlimit " ) ) { NEXT_UINT32 ( memLimit ) ; continue ; }
if ( longCommandWArg ( & argument , " --memory " ) ) { NEXT_UINT32 ( memLimit ) ; continue ; }
if ( longCommandWArg ( & argument , " --memlimit-decompress " ) ) { NEXT_UINT32 ( memLimit ) ; continue ; }
2020-02-20 11:29:58 -08:00
if ( longCommandWArg ( & argument , " --block-size= " ) ) { blockSize = readSizeTFromChar ( & argument ) ; continue ; }
2020-07-20 17:41:32 -07:00
if ( longCommandWArg ( & argument , " --maxdict " ) ) { NEXT_UINT32 ( maxDictSize ) ; continue ; }
if ( longCommandWArg ( & argument , " --dictID " ) ) { NEXT_UINT32 ( dictID ) ; continue ; }
2019-12-02 16:08:08 -08:00
if ( longCommandWArg ( & argument , " --zstd= " ) ) { if ( ! parseCompressionParameters ( argument , & compressionParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; } continue ; }
2020-02-20 11:29:58 -08:00
if ( longCommandWArg ( & argument , " --stream-size= " ) ) { streamSrcSize = readSizeTFromChar ( & argument ) ; continue ; }
if ( longCommandWArg ( & argument , " --target-compressed-block-size= " ) ) { targetCBlockSize = readSizeTFromChar ( & argument ) ; continue ; }
if ( longCommandWArg ( & argument , " --size-hint= " ) ) { srcSizeHint = readSizeTFromChar ( & argument ) ; continue ; }
2020-07-20 17:41:32 -07:00
if ( longCommandWArg ( & argument , " --output-dir-flat " ) ) { NEXT_FIELD ( outDirName ) ; continue ; }
2021-06-16 06:38:43 -07:00
# ifdef ZSTD_MULTITHREAD
if ( longCommandWArg ( & argument , " --auto-threads " ) ) {
const char * threadDefault = NULL ;
NEXT_FIELD ( threadDefault ) ;
if ( strcmp ( threadDefault , " logical " ) = = 0 )
defaultLogicalCores = 1 ;
continue ;
}
# endif
2020-07-20 17:41:32 -07:00
# ifdef UTIL_HAS_MIRRORFILELIST
if ( longCommandWArg ( & argument , " --output-dir-mirror " ) ) { NEXT_FIELD ( outMirroredDirName ) ; continue ; }
2021-02-03 19:53:00 -08:00
# endif
# ifndef ZSTD_NOTRACE
if ( longCommandWArg ( & argument , " --trace " ) ) { char const * traceFile ; NEXT_FIELD ( traceFile ) ; TRACE_enable ( traceFile ) ; continue ; }
2020-07-20 17:41:32 -07:00
# endif
if ( longCommandWArg ( & argument , " --patch-from " ) ) { NEXT_FIELD ( patchFromDictFileName ) ; continue ; }
2021-06-09 12:35:43 -07:00
if ( longCommandWArg ( & argument , " --long " ) ) {
unsigned ldmWindowLog = 0 ;
ldmFlag = 1 ;
/* Parse optional window log */
if ( * argument = = ' = ' ) {
+ + argument ;
ldmWindowLog = readU32FromChar ( & argument ) ;
} else if ( * argument ! = 0 ) {
/* Invalid character following --long */
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
}
/* Only set windowLog if not already set by --zstd */
if ( compressionParams . windowLog = = 0 )
compressionParams . windowLog = ldmWindowLog ;
continue ;
}
2018-09-22 17:21:39 -07:00
# ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */
2019-11-05 17:02:43 -08:00
if ( longCommandWArg ( & argument , " --fast " ) ) {
/* Parse optional acceleration factor */
if ( * argument = = ' = ' ) {
U32 const maxFast = ( U32 ) - ZSTD_minCLevel ( ) ;
U32 fastLevel ;
+ + argument ;
fastLevel = readU32FromChar ( & argument ) ;
if ( fastLevel > maxFast ) fastLevel = maxFast ;
if ( fastLevel ) {
2019-12-02 16:08:08 -08:00
dictCLevel = cLevel = - ( int ) fastLevel ;
2018-03-11 19:56:48 -07:00
} else {
2019-12-02 16:08:08 -08:00
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
2018-03-11 19:56:48 -07:00
}
2019-11-05 17:02:43 -08:00
} else if ( * argument ! = 0 ) {
/* Invalid character following --fast */
2019-12-02 16:08:08 -08:00
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
2019-11-05 17:02:43 -08:00
} else {
cLevel = - 1 ; /* default for --fast */
2018-03-11 19:56:48 -07:00
}
2019-11-05 17:02:43 -08:00
continue ;
}
2018-09-22 17:21:39 -07:00
# endif
2019-10-14 23:49:13 -07:00
2020-07-20 17:41:32 -07:00
if ( longCommandWArg ( & argument , " --filelist " ) ) {
const char * listName ;
NEXT_FIELD ( listName ) ;
UTIL_refFilename ( file_of_names , listName ) ;
2019-11-05 17:02:43 -08:00
continue ;
}
2019-10-14 23:49:13 -07:00
2019-11-05 17:02:43 -08:00
/* fall-through, will trigger bad_usage() later on */
}
2019-10-14 23:49:13 -07:00
2019-11-05 17:02:43 -08:00
argument + + ;
while ( argument [ 0 ] ! = 0 ) {
2020-07-17 13:09:23 -07:00
2016-09-01 15:05:57 -07:00
# ifndef ZSTD_NOCOMPRESS
2019-11-05 17:02:43 -08:00
/* compression Level */
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
dictCLevel = cLevel = ( int ) readU32FromChar ( & argument ) ;
continue ;
}
2016-09-01 15:05:57 -07:00
# endif
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
switch ( argument [ 0 ] )
{
/* Display help */
2019-12-02 16:08:08 -08:00
case ' V ' : printVersion ( ) ; CLEAN_RETURN ( 0 ) ; /* Version Only */
2019-11-05 17:02:43 -08:00
case ' H ' :
2019-12-02 16:08:08 -08:00
case ' h ' : usage_advanced ( programName ) ; CLEAN_RETURN ( 0 ) ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Compress */
case ' z ' : operation = zom_compress ; argument + + ; break ;
2016-10-28 13:58:31 -07:00
2019-11-05 17:02:43 -08:00
/* Decoding */
case ' d ' :
2016-12-06 17:56:20 -08:00
# ifndef ZSTD_NOBENCH
2019-11-05 17:02:43 -08:00
benchParams . mode = BMK_decodeOnly ;
if ( operation = = zom_bench ) { argument + + ; break ; } /* benchmark decode (hidden option) */
2016-12-06 17:56:20 -08:00
# endif
2019-11-05 17:02:43 -08:00
operation = zom_decompress ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Force stdout, even if stdout==console */
case ' c ' : forceStdout = 1 ; outFileName = stdoutmark ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Use file content as dictionary */
2020-07-20 17:41:32 -07:00
case ' D ' : argument + + ; NEXT_FIELD ( dictFileName ) ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Overwrite */
2021-05-04 13:24:46 -07:00
case ' f ' : FIO_overwriteMode ( prefs ) ; forceStdin = 1 ; forceStdout = 1 ; followLinks = 1 ; allowBlockDevices = 1 ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Verbose mode */
case ' v ' : g_displayLevel + + ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Quiet mode */
case ' q ' : g_displayLevel - - ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* keep source file (default) */
case ' k ' : FIO_setRemoveSrcFile ( prefs , 0 ) ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Checksum */
case ' C ' : FIO_setChecksumFlag ( prefs , 2 ) ; argument + + ; break ;
2016-06-02 08:05:50 -07:00
2019-11-05 17:02:43 -08:00
/* test compressed file */
case ' t ' : operation = zom_test ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* destination file name */
2020-07-20 17:41:32 -07:00
case ' o ' : argument + + ; NEXT_FIELD ( outFileName ) ; break ;
2019-10-17 15:27:25 -07:00
2020-01-10 14:25:24 -08:00
/* limit memory */
2019-11-05 17:02:43 -08:00
case ' M ' :
argument + + ;
memLimit = readU32FromChar ( & argument ) ;
break ;
case ' l ' : operation = zom_list ; argument + + ; break ;
2016-09-13 08:50:08 -07:00
# ifdef UTIL_HAS_CREATEFILELIST
2019-11-05 17:02:43 -08:00
/* recursive */
case ' r ' : recursive = 1 ; argument + + ; break ;
2016-09-13 08:50:08 -07:00
# endif
2016-05-28 20:16:05 -07:00
2016-09-01 15:05:57 -07:00
# ifndef ZSTD_NOBENCH
2019-11-05 17:02:43 -08:00
/* Benchmark */
case ' b ' :
operation = zom_bench ;
argument + + ;
break ;
/* range bench (benchmark only) */
case ' e ' :
/* compression Level */
argument + + ;
cLevelLast = ( int ) readU32FromChar ( & argument ) ;
break ;
/* Modify Nb Iterations (benchmark only) */
case ' i ' :
argument + + ;
bench_nbSeconds = readU32FromChar ( & argument ) ;
break ;
/* cut input into blocks (benchmark only) */
case ' B ' :
argument + + ;
blockSize = readU32FromChar ( & argument ) ;
break ;
/* benchmark files separately (hidden option) */
case ' S ' :
argument + + ;
separateFiles = 1 ;
break ;
2017-11-17 00:22:55 -08:00
2017-01-19 16:59:56 -08:00
# endif /* ZSTD_NOBENCH */
2019-11-05 17:02:43 -08:00
/* nb of threads (hidden option) */
case ' T ' :
argument + + ;
nbWorkers = ( int ) readU32FromChar ( & argument ) ;
break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Dictionary Selection level */
case ' s ' :
argument + + ;
dictSelect = readU32FromChar ( & argument ) ;
break ;
2016-05-28 20:16:05 -07:00
2019-11-05 17:02:43 -08:00
/* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
case ' p ' : argument + + ;
2016-09-01 15:05:57 -07:00
# ifndef ZSTD_NOBENCH
2019-11-05 17:02:43 -08:00
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
benchParams . additionalParam = ( int ) readU32FromChar ( & argument ) ;
} else
2016-09-01 15:05:57 -07:00
# endif
2019-11-05 17:02:43 -08:00
main_pause = 1 ;
2018-06-19 10:58:22 -07:00
break ;
2019-11-05 17:02:43 -08:00
/* Select compressibility of synthetic sample */
case ' P ' :
2020-07-20 17:41:32 -07:00
argument + + ;
2019-11-05 17:02:43 -08:00
compressibility = ( double ) readU32FromChar ( & argument ) / 100 ;
2020-07-20 17:41:32 -07:00
break ;
2016-07-04 09:16:16 -07:00
2019-11-05 17:02:43 -08:00
/* unknown command */
2019-12-02 16:08:08 -08:00
default : badusage ( programName ) ; CLEAN_RETURN ( 1 ) ;
2019-11-05 17:02:43 -08:00
}
2016-07-04 09:16:16 -07:00
}
2019-11-05 17:02:43 -08:00
continue ;
} /* if (argument[0]=='-') */
/* none of the above : add filename to list */
UTIL_refFilename ( filenames , argument ) ;
2016-05-28 20:16:05 -07:00
}
/* Welcome message (if verbose) */
DISPLAYLEVEL ( 3 , WELCOME_MESSAGE ) ;
2018-02-13 14:56:35 -08:00
# ifdef ZSTD_MULTITHREAD
if ( ( nbWorkers = = 0 ) & & ( ! singleThread ) ) {
2018-02-01 19:29:30 -08:00
/* automatically set # workers based on # of reported cpus */
2021-06-16 06:38:43 -07:00
if ( defaultLogicalCores ) {
nbWorkers = UTIL_countLogicalCores ( ) ;
DISPLAYLEVEL ( 3 , " Note: %d logical core(s) detected \n " , nbWorkers ) ;
} else {
nbWorkers = UTIL_countPhysicalCores ( ) ;
DISPLAYLEVEL ( 3 , " Note: %d physical core(s) detected \n " , nbWorkers ) ;
}
2017-04-13 12:28:28 -07:00
}
2018-06-26 01:22:45 -07:00
# else
2018-06-29 17:10:56 -07:00
( void ) singleThread ; ( void ) nbWorkers ;
2018-02-13 14:56:35 -08:00
# endif
2017-03-23 11:52:09 -07:00
2017-03-23 12:09:35 -07:00
g_utilDisplayLevel = g_displayLevel ;
2021-06-09 12:22:59 -07:00
# ifdef UTIL_HAS_CREATEFILELIST
2017-03-23 11:52:09 -07:00
if ( ! followLinks ) {
2019-11-05 17:02:43 -08:00
unsigned u , fileNamesNb ;
unsigned const nbFilenames = ( unsigned ) filenames - > tableSize ;
for ( u = 0 , fileNamesNb = 0 ; u < nbFilenames ; u + + ) {
2019-11-26 11:20:26 -08:00
if ( UTIL_isLink ( filenames - > fileNames [ u ] )
& & ! UTIL_isFIFO ( filenames - > fileNames [ u ] )
2019-10-25 14:06:50 -07:00
) {
2019-11-26 11:20:26 -08:00
DISPLAYLEVEL ( 2 , " Warning : %s is a symbolic link, ignoring \n " , filenames - > fileNames [ u ] ) ;
2017-03-23 11:52:09 -07:00
} else {
2019-11-05 17:02:43 -08:00
filenames - > fileNames [ fileNamesNb + + ] = filenames - > fileNames [ u ] ;
2019-10-25 18:16:45 -07:00
} }
2019-11-05 17:02:43 -08:00
if ( fileNamesNb = = 0 & & nbFilenames > 0 ) /* all names are eliminated */
2019-02-11 15:07:32 -08:00
CLEAN_RETURN ( 1 ) ;
2019-11-05 17:02:43 -08:00
filenames - > tableSize = fileNamesNb ;
} /* if (!followLinks) */
/* read names from a file */
if ( file_of_names - > tableSize ) {
size_t const nbFileLists = file_of_names - > tableSize ;
size_t flNb ;
for ( flNb = 0 ; flNb < nbFileLists ; flNb + + ) {
FileNamesTable * const fnt = UTIL_createFileNamesTable_fromFileName ( file_of_names - > fileNames [ flNb ] ) ;
if ( fnt = = NULL ) {
DISPLAYLEVEL ( 1 , " zstd: error reading %s \n " , file_of_names - > fileNames [ flNb ] ) ;
CLEAN_RETURN ( 1 ) ;
}
2019-11-06 09:10:05 -08:00
filenames = UTIL_mergeFileNamesTable ( filenames , fnt ) ;
2019-11-05 17:02:43 -08:00
}
2017-03-23 11:52:09 -07:00
}
2019-11-05 17:02:43 -08:00
2016-09-21 03:24:43 -07:00
if ( recursive ) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */
2019-11-06 09:10:05 -08:00
UTIL_expandFNT ( & filenames , followLinks ) ;
2019-11-05 17:02:43 -08:00
}
2018-06-26 01:22:45 -07:00
# else
( void ) followLinks ;
2016-05-28 20:16:05 -07:00
# endif
2017-08-18 18:30:41 -07:00
2017-06-15 17:46:49 -07:00
if ( operation = = zom_list ) {
2017-08-18 18:30:41 -07:00
# ifndef ZSTD_NODECOMPRESS
2019-11-05 17:02:43 -08:00
int const ret = FIO_listMultipleFiles ( ( unsigned ) filenames - > tableSize , filenames - > fileNames , g_displayLevel ) ;
2017-06-20 12:43:10 -07:00
CLEAN_RETURN ( ret ) ;
2017-08-18 18:30:41 -07:00
# else
DISPLAY ( " file information is not supported \n " ) ;
CLEAN_RETURN ( 1 ) ;
# endif
2017-06-05 14:45:31 -07:00
}
2017-08-18 18:30:41 -07:00
2016-05-28 20:16:05 -07:00
/* Check if benchmark is selected */
2016-10-28 13:58:31 -07:00
if ( operation = = zom_bench ) {
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOBENCH
2018-08-03 07:54:29 -07:00
benchParams . blockSize = blockSize ;
benchParams . nbWorkers = nbWorkers ;
2019-10-17 15:27:25 -07:00
benchParams . realTime = ( unsigned ) setRealTimePrio ;
2018-08-03 07:54:29 -07:00
benchParams . nbSeconds = bench_nbSeconds ;
benchParams . ldmFlag = ldmFlag ;
2019-10-17 15:27:25 -07:00
benchParams . ldmMinMatch = ( int ) g_ldmMinMatch ;
benchParams . ldmHashLog = ( int ) g_ldmHashLog ;
2020-11-02 17:52:29 -08:00
benchParams . useRowMatchFinder = useRowMatchFinder ;
2017-09-02 21:10:36 -07:00
if ( g_ldmBucketSizeLog ! = LDM_PARAM_DEFAULT ) {
2019-10-17 15:27:25 -07:00
benchParams . ldmBucketSizeLog = ( int ) g_ldmBucketSizeLog ;
2017-09-02 21:10:36 -07:00
}
2018-11-21 14:36:57 -08:00
if ( g_ldmHashRateLog ! = LDM_PARAM_DEFAULT ) {
2019-10-17 15:27:25 -07:00
benchParams . ldmHashRateLog = ( int ) g_ldmHashRateLog ;
2017-09-02 21:10:36 -07:00
}
2019-02-15 15:24:55 -08:00
benchParams . literalCompressionMode = literalCompressionMode ;
2018-06-15 13:21:08 -07:00
2018-06-18 15:06:31 -07:00
if ( cLevel > ZSTD_maxCLevel ( ) ) cLevel = ZSTD_maxCLevel ( ) ;
if ( cLevelLast > ZSTD_maxCLevel ( ) ) cLevelLast = ZSTD_maxCLevel ( ) ;
if ( cLevelLast < cLevel ) cLevelLast = cLevel ;
2018-07-09 18:24:07 -07:00
if ( cLevelLast > cLevel )
2018-08-28 11:21:09 -07:00
DISPLAYLEVEL ( 3 , " Benchmarking levels from %d to %d \n " , cLevel , cLevelLast ) ;
2019-11-05 17:02:43 -08:00
if ( filenames - > tableSize > 0 ) {
2018-06-19 10:58:22 -07:00
if ( separateFiles ) {
unsigned i ;
2019-11-05 17:02:43 -08:00
for ( i = 0 ; i < filenames - > tableSize ; i + + ) {
2018-06-19 10:58:22 -07:00
int c ;
2019-11-05 17:02:43 -08:00
DISPLAYLEVEL ( 3 , " Benchmarking %s \n " , filenames - > fileNames [ i ] ) ;
2018-06-19 10:58:22 -07:00
for ( c = cLevel ; c < = cLevelLast ; c + + ) {
2019-11-05 17:02:43 -08:00
BMK_benchFilesAdvanced ( & filenames - > fileNames [ i ] , 1 , dictFileName , c , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 16:36:59 -07:00
} }
2018-06-19 10:58:22 -07:00
} else {
for ( ; cLevel < = cLevelLast ; cLevel + + ) {
2019-11-05 17:02:43 -08:00
BMK_benchFilesAdvanced ( filenames - > fileNames , ( unsigned ) filenames - > tableSize , dictFileName , cLevel , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 16:36:59 -07:00
} }
2018-06-18 15:06:31 -07:00
} else {
for ( ; cLevel < = cLevelLast ; cLevel + + ) {
2018-08-03 07:54:29 -07:00
BMK_syntheticTest ( cLevel , compressibility , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 16:36:59 -07:00
} }
2018-06-15 13:21:08 -07:00
2017-12-01 17:42:46 -08:00
# else
2018-08-03 08:30:01 -07:00
( void ) bench_nbSeconds ; ( void ) blockSize ; ( void ) setRealTimePrio ; ( void ) separateFiles ; ( void ) compressibility ;
2016-05-28 20:16:05 -07:00
# endif
goto _end ;
}
/* Check if dictionary builder is selected */
2016-10-28 13:58:31 -07:00
if ( operation = = zom_train ) {
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NODICT
2017-06-26 21:07:14 -07:00
ZDICT_params_t zParams ;
zParams . compressionLevel = dictCLevel ;
2019-10-17 15:27:25 -07:00
zParams . notificationLevel = ( unsigned ) g_displayLevel ;
2017-06-26 21:07:14 -07:00
zParams . dictID = dictID ;
2018-08-23 12:06:20 -07:00
if ( dict = = cover ) {
2017-05-01 23:40:20 -07:00
int const optimize = ! coverParams . k | | ! coverParams . d ;
2019-10-17 15:27:25 -07:00
coverParams . nbThreads = ( unsigned ) nbWorkers ;
2017-06-26 21:07:14 -07:00
coverParams . zParams = zParams ;
2021-10-04 17:47:52 -07:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( int ) filenames - > tableSize , blockSize , NULL , & coverParams , NULL , optimize ) ;
2018-08-23 12:06:20 -07:00
} else if ( dict = = fastCover ) {
int const optimize = ! fastCoverParams . k | | ! fastCoverParams . d ;
2019-10-17 15:27:25 -07:00
fastCoverParams . nbThreads = ( unsigned ) nbWorkers ;
2018-08-23 12:06:20 -07:00
fastCoverParams . zParams = zParams ;
2021-10-04 17:47:52 -07:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( int ) filenames - > tableSize , blockSize , NULL , NULL , & fastCoverParams , optimize ) ;
2016-12-31 21:08:24 -08:00
} else {
2017-06-26 21:07:14 -07:00
ZDICT_legacy_params_t dictParams ;
2016-12-31 21:08:24 -08:00
memset ( & dictParams , 0 , sizeof ( dictParams ) ) ;
dictParams . selectivityLevel = dictSelect ;
2017-06-26 21:07:14 -07:00
dictParams . zParams = zParams ;
2021-10-04 17:47:52 -07:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( int ) filenames - > tableSize , blockSize , & dictParams , NULL , NULL , 0 ) ;
2016-12-31 21:08:24 -08:00
}
2018-09-24 00:52:19 -07:00
# else
( void ) dictCLevel ; ( void ) dictSelect ; ( void ) dictID ; ( void ) maxDictSize ; /* not used when ZSTD_NODICT set */
DISPLAYLEVEL ( 1 , " training mode not available \n " ) ;
operationResult = 1 ;
2016-05-28 20:16:05 -07:00
# endif
goto _end ;
}
2017-07-18 14:45:49 -07:00
# ifndef ZSTD_NODECOMPRESS
2019-10-17 16:09:53 -07:00
if ( operation = = zom_test ) { FIO_setTestMode ( prefs , 1 ) ; outFileName = nulmark ; FIO_setRemoveSrcFile ( prefs , 0 ) ; } /* test mode */
2017-07-18 14:45:49 -07:00
# endif
2016-05-28 20:16:05 -07:00
/* No input filename ==> use stdin and stdout */
2019-11-05 17:02:43 -08:00
if ( filenames - > tableSize = = 0 ) UTIL_refFilename ( filenames , stdinmark ) ;
if ( ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark ) & & ! outFileName )
2018-03-11 19:56:48 -07:00
outFileName = stdoutmark ; /* when input is stdin, default output is stdout */
2016-05-28 20:16:05 -07:00
/* Check if input/output defined as console; trigger an error in this case */
2021-01-11 14:53:20 -08:00
if ( ! forceStdin
& & ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark )
& & IS_CONSOLE ( stdin ) ) {
2020-09-28 09:15:18 -07:00
DISPLAYLEVEL ( 1 , " stdin is a console, aborting \n " ) ;
2019-12-02 16:08:08 -08:00
CLEAN_RETURN ( 1 ) ;
}
2018-03-11 19:56:48 -07:00
if ( outFileName & & ! strcmp ( outFileName , stdoutmark )
& & IS_CONSOLE ( stdout )
2019-11-05 17:02:43 -08:00
& & ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark )
2018-03-11 19:56:48 -07:00
& & ! forceStdout
2019-12-02 16:08:08 -08:00
& & operation ! = zom_decompress ) {
2020-09-28 09:15:18 -07:00
DISPLAYLEVEL ( 1 , " stdout is a console, aborting \n " ) ;
2019-12-02 16:08:08 -08:00
CLEAN_RETURN ( 1 ) ;
}
2016-05-28 20:16:05 -07:00
2016-10-05 02:56:22 -07:00
# ifndef ZSTD_NOCOMPRESS
2016-08-12 09:04:15 -07:00
/* check compression level limits */
{ int const maxCLevel = ultra ? ZSTD_maxCLevel ( ) : ZSTDCLI_CLEVEL_MAX ;
if ( cLevel > maxCLevel ) {
DISPLAYLEVEL ( 2 , " Warning : compression level higher than max, reduced to %i \n " , maxCLevel ) ;
cLevel = maxCLevel ;
} }
2016-10-05 02:56:22 -07:00
# endif
2016-08-12 09:04:15 -07:00
2020-01-30 14:12:03 -08:00
if ( showDefaultCParams ) {
if ( operation = = zom_decompress ) {
DISPLAY ( " error : can't use --show-default-cparams in decomrpession mode \n " ) ;
CLEAN_RETURN ( 1 ) ;
}
}
2020-01-10 14:25:24 -08:00
if ( dictFileName ! = NULL & & patchFromDictFileName ! = NULL ) {
DISPLAY ( " error : can't use -D and --patch-from=# at the same time \n " ) ;
CLEAN_RETURN ( 1 ) ;
}
2020-04-17 13:58:53 -07:00
if ( patchFromDictFileName ! = NULL & & filenames - > tableSize > 1 ) {
DISPLAY ( " error : can't use --patch-from=# on multiple files \n " ) ;
CLEAN_RETURN ( 1 ) ;
}
2021-01-07 10:37:27 -08:00
/* No status message in pipe mode (stdin - stdout) */
2020-10-07 10:47:38 -07:00
hasStdout = outFileName & & ! strcmp ( outFileName , stdoutmark ) ;
if ( hasStdout & & ( g_displayLevel = = 2 ) ) g_displayLevel = 1 ;
2016-05-28 20:16:05 -07:00
/* IO Stream/File */
2020-10-07 10:47:38 -07:00
FIO_setHasStdoutOutput ( fCtx , hasStdout ) ;
2021-01-07 10:37:27 -08:00
FIO_setNbFilesTotal ( fCtx , ( int ) filenames - > tableSize ) ;
2020-09-24 12:55:30 -07:00
FIO_determineHasStdinInput ( fCtx , filenames ) ;
2017-03-23 11:13:52 -07:00
FIO_setNotificationLevel ( g_displayLevel ) ;
2021-05-04 13:24:46 -07:00
FIO_setAllowBlockDevices ( prefs , allowBlockDevices ) ;
2020-01-10 14:25:24 -08:00
FIO_setPatchFromMode ( prefs , patchFromDictFileName ! = NULL ) ;
if ( memLimit = = 0 ) {
if ( compressionParams . windowLog = = 0 ) {
memLimit = ( U32 ) 1 < < g_defaultMaxWindowLog ;
} else {
memLimit = ( U32 ) 1 < < ( compressionParams . windowLog & 31 ) ;
} }
2020-04-17 13:58:53 -07:00
if ( patchFromDictFileName ! = NULL )
dictFileName = patchFromDictFileName ;
2020-01-10 14:25:24 -08:00
FIO_setMemLimit ( prefs , memLimit ) ;
2016-10-28 13:58:31 -07:00
if ( operation = = zom_compress ) {
2016-09-21 03:24:43 -07:00
# ifndef ZSTD_NOCOMPRESS
2020-03-09 12:12:52 -07:00
FIO_setContentSize ( prefs , contentSize ) ;
2019-01-22 17:31:13 -08:00
FIO_setNbWorkers ( prefs , nbWorkers ) ;
2019-10-17 15:27:25 -07:00
FIO_setBlockSize ( prefs , ( int ) blockSize ) ;
if ( g_overlapLog ! = OVERLAP_LOG_DEFAULT ) FIO_setOverlapLog ( prefs , ( int ) g_overlapLog ) ;
FIO_setLdmFlag ( prefs , ( unsigned ) ldmFlag ) ;
FIO_setLdmHashLog ( prefs , ( int ) g_ldmHashLog ) ;
FIO_setLdmMinMatch ( prefs , ( int ) g_ldmMinMatch ) ;
if ( g_ldmBucketSizeLog ! = LDM_PARAM_DEFAULT ) FIO_setLdmBucketSizeLog ( prefs , ( int ) g_ldmBucketSizeLog ) ;
if ( g_ldmHashRateLog ! = LDM_PARAM_DEFAULT ) FIO_setLdmHashRateLog ( prefs , ( int ) g_ldmHashRateLog ) ;
FIO_setAdaptiveMode ( prefs , ( unsigned ) adapt ) ;
2020-11-02 17:52:29 -08:00
FIO_setUseRowMatchFinder ( prefs , useRowMatchFinder ) ;
2019-01-22 17:31:13 -08:00
FIO_setAdaptMin ( prefs , adaptMin ) ;
FIO_setAdaptMax ( prefs , adaptMax ) ;
FIO_setRsyncable ( prefs , rsyncable ) ;
2019-08-15 23:57:55 -07:00
FIO_setStreamSrcSize ( prefs , streamSrcSize ) ;
2019-06-24 13:40:52 -07:00
FIO_setTargetCBlockSize ( prefs , targetCBlockSize ) ;
2019-08-19 08:52:08 -07:00
FIO_setSrcSizeHint ( prefs , srcSizeHint ) ;
2019-02-15 15:24:55 -08:00
FIO_setLiteralCompressionMode ( prefs , literalCompressionMode ) ;
2018-09-24 18:16:08 -07:00
if ( adaptMin > cLevel ) cLevel = adaptMin ;
if ( adaptMax < cLevel ) cLevel = adaptMax ;
2017-09-01 14:52:51 -07:00
2020-02-03 09:52:39 -08:00
/* Compare strategies constant with the ground truth */
{ ZSTD_bounds strategyBounds = ZSTD_cParam_getBounds ( ZSTD_c_strategy ) ;
2020-05-08 13:42:15 -07:00
assert ( ZSTD_NB_STRATEGIES = = strategyBounds . upperBound ) ;
( void ) strategyBounds ; }
2020-01-31 10:47:17 -08:00
2021-11-05 12:48:13 -07:00
if ( showDefaultCParams | | g_displayLevel > = 4 ) {
2020-01-30 14:12:03 -08:00
size_t fileNb ;
for ( fileNb = 0 ; fileNb < ( size_t ) filenames - > tableSize ; fileNb + + ) {
2021-11-05 12:48:13 -07:00
if ( showDefaultCParams )
printDefaultCParams ( filenames - > fileNames [ fileNb ] , dictFileName , cLevel ) ;
if ( g_displayLevel > = 4 )
printActualCParams ( filenames - > fileNames [ fileNb ] , dictFileName , cLevel , & compressionParams ) ;
2020-01-30 14:12:03 -08:00
}
}
2021-11-05 12:01:20 -07:00
if ( g_displayLevel > = 4 )
FIO_displayCompressionParameters ( prefs ) ;
2019-11-05 17:02:43 -08:00
if ( ( filenames - > tableSize = = 1 ) & & outFileName )
2020-09-07 10:13:05 -07:00
operationResult = FIO_compressFilename ( fCtx , prefs , outFileName , filenames - > fileNames [ 0 ] , dictFileName , cLevel , compressionParams ) ;
2016-05-28 20:16:05 -07:00
else
2020-09-07 10:13:05 -07:00
operationResult = FIO_compressMultipleFilenames ( fCtx , prefs , filenames - > fileNames , outMirroredDirName , outDirName , outFileName , suffix , dictFileName , cLevel , compressionParams ) ;
2016-09-21 03:24:43 -07:00
# else
2020-11-02 17:52:29 -08:00
( 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 */
2018-09-24 16:56:45 -07:00
DISPLAY ( " Compression not supported \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
2016-10-28 13:58:31 -07:00
} else { /* decompression or test */
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NODECOMPRESS
2019-11-05 17:02:43 -08:00
if ( filenames - > tableSize = = 1 & & outFileName ) {
2020-09-07 10:13:05 -07:00
operationResult = FIO_decompressFilename ( fCtx , prefs , outFileName , filenames - > fileNames [ 0 ] , dictFileName ) ;
2019-10-25 16:36:59 -07:00
} else {
2020-09-07 10:13:05 -07:00
operationResult = FIO_decompressMultipleFilenames ( fCtx , prefs , filenames - > fileNames , outMirroredDirName , outDirName , outFileName , dictFileName ) ;
2019-10-25 16:36:59 -07:00
}
2016-05-28 20:16:05 -07:00
# else
2018-09-24 16:56:45 -07:00
DISPLAY ( " Decompression not supported \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
}
_end :
2019-01-22 17:31:13 -08:00
FIO_freePreferences ( prefs ) ;
2020-09-03 07:14:04 -07:00
FIO_freeContext ( fCtx ) ;
2016-05-28 20:16:05 -07:00
if ( main_pause ) waitEnter ( ) ;
2019-11-05 17:02:43 -08:00
UTIL_freeFileNamesTable ( filenames ) ;
UTIL_freeFileNamesTable ( file_of_names ) ;
2021-02-03 19:53:00 -08:00
# ifndef ZSTD_NOTRACE
TRACE_finish ( ) ;
# endif
2019-10-25 18:16:45 -07:00
2016-05-28 20:16:05 -07:00
return operationResult ;
}