2017-08-18 23:52:05 +00:00
/*
2020-03-26 22:19:05 +00:00
* Copyright ( c ) 2016 - 2020 , Yann Collet , Facebook , Inc .
2016-08-30 17:04:33 +00:00
* All rights reserved .
*
2017-08-18 23:52:05 +00: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 07:09:23 +00:00
* You may select , at your option , one of the above - listed licenses .
2016-08-30 17:04:33 +00:00
*/
2016-08-28 17:00:49 +00:00
2016-05-29 03:16:05 +00:00
2016-07-13 12:15:08 +00:00
/*-************************************
* Tuning parameters
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-07-13 13:16:00 +00:00
# ifndef ZSTDCLI_CLEVEL_DEFAULT
# define ZSTDCLI_CLEVEL_DEFAULT 3
2016-07-13 12:15:08 +00:00
# endif
2016-08-12 16:04:15 +00:00
# ifndef ZSTDCLI_CLEVEL_MAX
2017-08-19 20:33:50 +00:00
# define ZSTDCLI_CLEVEL_MAX 19 /* without using --ultra */
2016-08-12 16:04:15 +00:00
# endif
2016-07-13 12:15:08 +00:00
2017-01-26 01:01:13 +00:00
2016-05-29 03:16:05 +00:00
/*-************************************
2016-11-16 16:50:54 +00:00
* Dependencies
2016-05-29 03:16:05 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-12-21 14:08:44 +00:00
# include "platform.h" /* IS_CONSOLE, PLATFORM_POSIX_VERSION */
# include "util.h" /* UTIL_HAS_CREATEFILELIST, UTIL_createFileList */
2018-12-19 21:26:27 +00:00
# include <stdlib.h> /* getenv */
2016-05-29 03:16:05 +00:00
# include <string.h> /* strcmp, strlen */
2019-12-02 22:28:18 +00:00
# include <stdio.h> /* fprintf(), stdin, stdout, stderr */
2016-07-04 16:16:16 +00:00
# include <errno.h> /* errno */
2019-12-02 22:28:18 +00:00
# include <assert.h> /* assert */
2017-08-19 20:33:50 +00:00
# include "fileio.h" /* stdinmark, stdoutmark, ZSTD_EXTENSION */
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NOBENCH
2018-11-13 19:01:59 +00:00
# include "benchzstd.h" /* BMK_benchFiles */
2016-05-29 03:16:05 +00:00
# endif
# ifndef ZSTD_NODICT
2017-08-19 20:33:50 +00:00
# include "dibio.h" /* ZDICT_cover_params_t, DiB_trainFromFiles() */
2016-05-29 03:16:05 +00:00
# endif
2020-05-01 20:20:40 +00:00
# include "../lib/zstd.h" /* ZSTD_VERSION_STRING, ZSTD_minCLevel, ZSTD_maxCLevel */
2016-05-29 03:16:05 +00: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 18:33:04 +00:00
# define ZSTD_ZSTDMT "zstdmt"
2016-05-29 03:16:05 +00:00
# define ZSTD_UNZSTD "unzstd"
2017-02-14 18:45:19 +00:00
# define ZSTD_CAT "zstdcat"
2018-01-19 19:26:35 +00:00
# define ZSTD_ZCAT "zcat"
2017-02-14 18:45:19 +00:00
# define ZSTD_GZ "gzip"
# define ZSTD_GUNZIP "gunzip"
# define ZSTD_GZCAT "gzcat"
2017-03-14 01:11:07 +00:00
# define ZSTD_LZMA "lzma"
2017-06-26 18:24:36 +00:00
# define ZSTD_UNLZMA "unlzma"
2017-03-14 01:11:07 +00:00
# define ZSTD_XZ "xz"
2017-06-26 18:24:36 +00:00
# define ZSTD_UNXZ "unxz"
2017-09-28 23:18:15 +00:00
# define ZSTD_LZ4 "lz4"
# define ZSTD_UNLZ4 "unlz4"
2016-05-29 03:16:05 +00:00
# define KB *(1 <<10)
# define MB *(1 <<20)
# define GB *(1U<<30)
2017-08-19 20:33:50 +00:00
# define DISPLAY_LEVEL_DEFAULT 2
2016-08-12 21:49:05 +00:00
2016-05-29 03:16:05 +00:00
static const char * g_defaultDictName = " dictionary " ;
static const unsigned g_defaultMaxDictSize = 110 KB ;
2016-09-01 22:05:57 +00:00
static const int g_defaultDictCLevel = 3 ;
2016-05-29 03:16:05 +00:00
static const unsigned g_defaultSelectivityLevel = 9 ;
2017-09-22 21:04:39 +00:00
static const unsigned g_defaultMaxWindowLog = 27 ;
2017-01-30 22:37:08 +00:00
# define OVERLAP_LOG_DEFAULT 9999
2017-09-03 04:10:36 +00:00
# define LDM_PARAM_DEFAULT 9999 /* Default for parameters where 0 is valid */
2017-01-30 22:37:08 +00:00
static U32 g_overlapLog = OVERLAP_LOG_DEFAULT ;
2017-09-01 21:52:51 +00:00
static U32 g_ldmHashLog = 0 ;
static U32 g_ldmMinMatch = 0 ;
2018-11-21 22:36:57 +00:00
static U32 g_ldmHashRateLog = LDM_PARAM_DEFAULT ;
2017-09-03 04:10:36 +00:00
static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT ;
2016-05-29 03:16:05 +00:00
2018-08-23 19:06:20 +00:00
# define DEFAULT_ACCEL 1
typedef enum { cover , fastCover , legacy } dictType ;
2016-05-29 03:16:05 +00:00
/*-************************************
* Display Macros
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-12-03 00:08:08 +00: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 18:13:52 +00:00
# define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
2017-08-19 20:33:50 +00:00
static int g_displayLevel = DISPLAY_LEVEL_DEFAULT ; /* 0 : no display, 1: errors, 2 : + result + interaction + warnings, 3 : + progression, 4 : + information */
2016-05-29 03:16:05 +00:00
/*-************************************
* Command Line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-12-03 00:08:08 +00: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-29 03:16:05 +00:00
{
2019-12-03 00:08:08 +00: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-29 03:16:05 +00:00
# ifndef ZSTD_NOCOMPRESS
2019-12-03 00:08:08 +00:00
DISPLAY_F ( f , " -# : # compression level (1-%d, default: %d) \n " , ZSTDCLI_CLEVEL_MAX , ZSTDCLI_CLEVEL_DEFAULT ) ;
2016-05-29 03:16:05 +00:00
# endif
# ifndef ZSTD_NODECOMPRESS
2019-12-03 00:08:08 +00:00
DISPLAY_F ( f , " -d : decompression \n " ) ;
2016-05-29 03:16:05 +00:00
# endif
2020-05-08 21:14:46 +00:00
DISPLAY_F ( f , " -D DICT: use DICT as Dictionary for compression or decompression \n " ) ;
2020-05-08 21:20:47 +00:00
DISPLAY_F ( f , " -o file: result stored into `file` (only 1 output file) \n " ) ;
2020-05-08 21:14:46 +00:00
DISPLAY_F ( f , " -f : overwrite output without prompting, also (de)compress links \n " ) ;
2019-12-03 00:08:08 +00: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-29 03:16:05 +00:00
}
2019-12-03 00:08:08 +00:00
static void usage_advanced ( const char * programName )
2016-05-29 03:16:05 +00:00
{
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( WELCOME_MESSAGE ) ;
usage ( stdout , programName ) ;
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Advanced arguments : \n " ) ;
DISPLAYOUT ( " -V : display Version number and exit \n " ) ;
2020-05-08 21:14:46 +00:00
DISPLAYOUT ( " -c : force write to standard output, even if it is the console \n " ) ;
DISPLAYOUT ( " -v : verbose mode; specify multiple times to increase verbosity \n " ) ;
DISPLAYOUT ( " -q : suppress warnings; specify twice to suppress errors too \n " ) ;
DISPLAYOUT ( " --no-progress : do not display the progress counter \n " ) ;
# ifdef UTIL_HAS_CREATEFILELIST
DISPLAYOUT ( " -r : operate recursively on directories \n " ) ;
2020-07-23 19:10:57 +00: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 21:14:46 +00:00
# endif
2020-06-20 02:35:51 +00:00
# ifdef UTIL_HAS_MIRRORFILELIST
2020-07-23 19:10:57 +00:00
DISPLAYOUT ( " --output-dir-mirror DIR : processed files are stored into DIR respecting original directory structure \n " ) ;
2020-06-20 02:35:51 +00:00
# endif
2020-05-08 21:14:46 +00:00
DISPLAYOUT ( " -- : All arguments after \" -- \" are treated as files \n " ) ;
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NOCOMPRESS
2020-05-08 21:14:46 +00: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-03 00:08:08 +00:00
DISPLAYOUT ( " --adapt : dynamically adapt compression level to I/O conditions \n " ) ;
# 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 21:14:46 +00:00
DISPLAYOUT ( " --single-thread : use a single thread for both I/O and compression (result slightly different than -T1) \n " ) ;
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --rsyncable : compress using a rsync-friendly method (-B sets block size) \n " ) ;
# endif
2020-05-08 21:14:46 +00: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 " ) ;
DISPLAYOUT ( " --[no-]check : add XXH64 integrity checksum to frame (default: enabled) \n " ) ;
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --[no-]compress-literals : force (un)compressed literals \n " ) ;
2020-05-08 21:14:46 +00:00
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --format=zstd : compress files to the .zst format (default) \n " ) ;
2017-02-08 14:17:55 +00:00
# ifdef ZSTD_GZCOMPRESS
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --format=gzip : compress files to the .gz format \n " ) ;
2017-02-08 14:17:55 +00:00
# endif
2017-03-14 01:11:07 +00:00
# ifdef ZSTD_LZMACOMPRESS
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --format=xz : compress files to the .xz format \n " ) ;
DISPLAYOUT ( " --format=lzma : compress files to the .lzma format \n " ) ;
2017-03-14 01:11:07 +00:00
# endif
2017-04-24 23:48:25 +00:00
# ifdef ZSTD_LZ4COMPRESS
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --format=lz4 : compress files to the .lz4 format \n " ) ;
2017-04-24 23:48:25 +00:00
# endif
2020-05-08 21:14:46 +00:00
# endif /* !ZSTD_NOCOMPRESS */
2016-05-31 00:29:45 +00:00
# ifndef ZSTD_NODECOMPRESS
2020-05-08 21:14:46 +00:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Advanced decompression arguments : \n " ) ;
DISPLAYOUT ( " -l : print information about zstd compressed files \n " ) ;
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " --test : test compressed file integrity \n " ) ;
DISPLAYOUT ( " -M# : Set a memory usage limit for decompression \n " ) ;
2020-08-22 20:58:41 +00:00
DISPLAYOUT ( " --no-check : disable validation of checksums in compressed frame \n " ) ;
2020-05-08 21:14:46 +00: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-29 03:16:05 +00:00
# ifndef ZSTD_NODICT
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Dictionary builder : \n " ) ;
DISPLAYOUT ( " --train ## : create a dictionary from a training set of files \n " ) ;
2020-05-08 21:14:46 +00: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-03 00:08:08 +00:00
DISPLAYOUT ( " --maxdict=# : limit dictionary to specified size (default: %u) \n " , g_defaultMaxDictSize ) ;
2020-05-08 21:14:46 +00:00
DISPLAYOUT ( " --dictID=# : force dictionary ID to specified value (default: random) \n " ) ;
2016-05-29 03:16:05 +00:00
# endif
2020-05-08 21:14:46 +00:00
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NOBENCH
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " \n " ) ;
DISPLAYOUT ( " Benchmark arguments : \n " ) ;
DISPLAYOUT ( " -b# : benchmark file(s), using # compression level (default: %d) \n " , ZSTDCLI_CLEVEL_DEFAULT ) ;
2020-05-08 21:14:46 +00:00
DISPLAYOUT ( " -e# : test all compression levels successively from -b# to -e# (default: 1) \n " ) ;
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( " -i# : minimum evaluation time in seconds (default: 3s) \n " ) ;
2020-05-08 21:14:46 +00: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-03 00:08:08 +00:00
DISPLAYOUT ( " --priority=rt : set process priority to real-time \n " ) ;
2016-05-29 03:16:05 +00:00
# endif
2020-05-08 21:14:46 +00:00
2016-05-29 03:16:05 +00:00
}
2019-12-03 00:08:08 +00:00
static void badusage ( const char * programName )
2016-05-29 03:16:05 +00:00
{
2019-12-03 00:08:08 +00:00
DISPLAYLEVEL ( 1 , " Incorrect parameters \n " ) ;
if ( g_displayLevel > = 2 ) usage ( stderr , programName ) ;
2016-05-29 03:16:05 +00:00
}
static void waitEnter ( void )
{
int unused ;
2019-12-03 00:08:08 +00:00
DISPLAY ( " Press enter to continue... \n " ) ;
2016-05-29 03:16:05 +00:00
unused = getchar ( ) ;
( void ) unused ;
}
2017-03-25 00:06:09 +00: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 21:29:33 +00:00
static void errorOut ( const char * msg )
{
DISPLAY ( " %s \n " , msg ) ; exit ( 1 ) ;
}
2018-12-20 07:41:18 +00:00
/*! readU32FromCharChecked() :
2018-12-20 00:45:42 +00:00
* @ return 0 if success , and store the result in * value .
2018-03-12 02:56:48 +00: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-20 00:45:42 +00:00
* @ return 1 if an overflow error occurs */
2018-12-20 07:41:18 +00:00
static int readU32FromCharChecked ( const char * * stringPtr , unsigned * value )
2016-06-03 13:14:09 +00:00
{
unsigned result = 0 ;
2018-05-12 21:29:33 +00:00
while ( ( * * stringPtr > = ' 0 ' ) & & ( * * stringPtr < = ' 9 ' ) ) {
2020-02-18 23:30:59 +00:00
unsigned const max = ( ( unsigned ) ( - 1 ) ) / 10 ;
unsigned last = result ;
2019-04-10 17:03:06 +00:00
if ( result > max ) return 1 ; /* overflow error */
result * = 10 ;
result + = ( unsigned ) ( * * stringPtr - ' 0 ' ) ;
2020-02-18 23:30:59 +00:00
if ( result < last ) return 1 ; /* overflow error */
2019-04-10 17:03:06 +00:00
( * stringPtr ) + + ;
2018-05-12 21:29:33 +00:00
}
2016-10-18 00:48:48 +00:00
if ( ( * * stringPtr = = ' K ' ) | | ( * * stringPtr = = ' M ' ) ) {
2018-05-12 21:29:33 +00:00
unsigned const maxK = ( ( unsigned ) ( - 1 ) ) > > 10 ;
2019-04-10 17:03:06 +00:00
if ( result > maxK ) return 1 ; /* overflow error */
2016-10-18 00:48:48 +00:00
result < < = 10 ;
2018-05-12 21:29:33 +00:00
if ( * * stringPtr = = ' M ' ) {
2019-04-10 17:03:06 +00:00
if ( result > maxK ) return 1 ; /* overflow error */
2018-05-12 21:29:33 +00:00
result < < = 10 ;
}
( * stringPtr ) + + ; /* skip `K` or `M` */
2016-10-18 00:48:48 +00:00
if ( * * stringPtr = = ' i ' ) ( * stringPtr ) + + ;
if ( * * stringPtr = = ' B ' ) ( * stringPtr ) + + ;
}
2018-12-20 00:45:42 +00: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 19:29:58 +00:00
static const char errorMsg [ ] = " error: numeric value overflows 32-bit unsigned int " ;
2018-12-20 00:45:42 +00:00
unsigned result ;
2018-12-20 07:41:18 +00:00
if ( readU32FromCharChecked ( stringPtr , & result ) ) { errorOut ( errorMsg ) ; }
2016-06-03 13:14:09 +00:00
return result ;
}
2020-02-20 19:29:58 +00: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 23:18:57 +00:00
/** longCommandWArg() :
2017-01-30 21:07:24 +00:00
* check if * stringPtr is the same as longCommand .
2016-12-02 23:18:57 +00:00
* If yes , @ return 1 and advances * stringPtr to the position which immediately follows longCommand .
2018-03-12 02:56:48 +00:00
* @ return 0 and doesn ' t modify * stringPtr otherwise .
2016-12-02 23:18:57 +00:00
*/
2019-10-17 22:27:25 +00:00
static int longCommandWArg ( const char * * stringPtr , const char * longCommand )
2016-10-14 21:41:17 +00:00
{
size_t const comSize = strlen ( longCommand ) ;
2016-12-02 23:18:57 +00:00
int const result = ! strncmp ( * stringPtr , longCommand , comSize ) ;
2016-10-14 21:41:17 +00:00
if ( result ) * stringPtr + = comSize ;
return result ;
}
2016-12-13 11:18:07 +00:00
2017-01-01 05:08:24 +00:00
# ifndef ZSTD_NODICT
2019-07-18 18:44:59 +00:00
static const unsigned kDefaultRegression = 1 ;
2017-01-01 05:08:24 +00:00
/**
* parseCoverParameters ( ) :
2017-05-02 06:40:20 +00:00
* reads cover parameters from * stringPtr ( e . g . " --train-cover=k=48,d=8,steps=32 " ) into * params
2017-01-01 05:08:24 +00:00
* @ return 1 means that cover parameters were correct
* @ return 0 in case of malformed parameters
*/
2017-06-27 04:07:14 +00:00
static unsigned parseCoverParameters ( const char * stringPtr , ZDICT_cover_params_t * params )
2017-01-01 05:08:24 +00:00
{
memset ( params , 0 , sizeof ( * params ) ) ;
for ( ; ; ) {
2017-01-02 20:40:43 +00:00
if ( longCommandWArg ( & stringPtr , " k= " ) ) { params - > k = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-01-01 05:08:24 +00:00
if ( longCommandWArg ( & stringPtr , " d= " ) ) { params - > d = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-01-02 20:40:43 +00:00
if ( longCommandWArg ( & stringPtr , " steps= " ) ) { params - > steps = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-06-30 00:54:41 +00:00
if ( longCommandWArg ( & stringPtr , " split= " ) ) {
2018-07-04 00:53:27 +00:00
unsigned splitPercentage = readU32FromChar ( & stringPtr ) ;
2018-06-30 00:54:41 +00:00
params - > splitPoint = ( double ) splitPercentage / 100.0 ;
if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ;
}
2019-06-27 23:26:57 +00: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 ;
}
2017-01-01 05:08:24 +00:00
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
2019-06-27 23:26:57 +00: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 ) ;
2017-01-01 05:08:24 +00:00
return 1 ;
}
2017-05-02 06:40:20 +00:00
2018-08-23 19:06:20 +00: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 23:26:57 +00: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 19:06:20 +00:00
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
2019-06-27 23:26:57 +00: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 19:06:20 +00:00
return 1 ;
}
2017-05-02 06:40:20 +00:00
/**
* parseLegacyParameters ( ) :
2019-04-12 18:18:11 +00:00
* reads legacy dictionary builder parameters from * stringPtr ( e . g . " --train-legacy=selectivity=8 " ) into * selectivity
2017-05-02 06:40:20 +00: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-27 04:07:14 +00:00
static ZDICT_cover_params_t defaultCoverParams ( void )
2017-05-02 06:40:20 +00:00
{
2017-06-27 04:07:14 +00:00
ZDICT_cover_params_t params ;
2017-05-02 06:40:20 +00:00
memset ( & params , 0 , sizeof ( params ) ) ;
params . d = 8 ;
params . steps = 4 ;
2018-08-23 19:06:20 +00:00
params . splitPoint = 1.0 ;
2019-06-27 23:26:57 +00:00
params . shrinkDict = 0 ;
params . shrinkDictMaxRegression = kDefaultRegression ;
2018-08-23 19:06:20 +00: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-05 00:12:35 +00:00
params . f = 20 ;
2018-08-23 19:06:20 +00:00
params . steps = 4 ;
params . splitPoint = 0.75 ; /* different from default splitPoint of cover */
params . accel = DEFAULT_ACCEL ;
2019-06-27 23:26:57 +00:00
params . shrinkDict = 0 ;
params . shrinkDictMaxRegression = kDefaultRegression ;
2017-05-02 06:40:20 +00:00
return params ;
}
2017-01-01 05:08:24 +00:00
# endif
2017-01-30 21:07:24 +00:00
2018-09-25 01:16:08 +00: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 ( ; ; ) {
2019-10-17 22:27:25 +00:00
if ( longCommandWArg ( & stringPtr , " min= " ) ) { * adaptMinPtr = ( int ) readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " max= " ) ) { * adaptMaxPtr = ( int ) readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-09-25 01:16:08 +00: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 11:18:07 +00:00
/** parseCompressionParameters() :
2018-11-20 22:56:07 +00: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 11:18:07 +00: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 22:56:07 +00:00
if ( longCommandWArg ( & stringPtr , " minMatch= " ) | | longCommandWArg ( & stringPtr , " mml= " ) ) { params - > minMatch = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2016-12-13 11:18:07 +00:00
if ( longCommandWArg ( & stringPtr , " targetLength= " ) | | longCommandWArg ( & stringPtr , " tlen= " ) ) { params - > targetLength = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-06-20 21:11:49 +00:00
if ( longCommandWArg ( & stringPtr , " strategy= " ) | | longCommandWArg ( & stringPtr , " strat= " ) ) { params - > strategy = ( ZSTD_strategy ) ( readU32FromChar ( & stringPtr ) ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-01-30 21:07:24 +00:00
if ( longCommandWArg ( & stringPtr , " overlapLog= " ) | | longCommandWArg ( & stringPtr , " ovlog= " ) ) { g_overlapLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2018-11-20 22:56:07 +00: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 22:36:57 +00:00
if ( longCommandWArg ( & stringPtr , " ldmHashRateLog= " ) | | longCommandWArg ( & stringPtr , " lhrlog= " ) ) { g_ldmHashRateLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-12-27 12:32:05 +00:00
DISPLAYLEVEL ( 4 , " invalid compression parameter \n " ) ;
2016-12-13 11:18:07 +00:00
return 0 ;
}
2017-12-27 12:32:05 +00:00
DISPLAYLEVEL ( 4 , " windowLog=%d, chainLog=%d, hashLog=%d, searchLog=%d \n " , params - > windowLog , params - > chainLog , params - > hashLog , params - > searchLog ) ;
2018-11-20 22:56:07 +00:00
DISPLAYLEVEL ( 4 , " minMatch=%d, targetLength=%d, strategy=%d \n " , params - > minMatch , params - > targetLength , params - > strategy ) ;
2016-12-13 11:18:07 +00:00
if ( stringPtr [ 0 ] ! = 0 ) return 0 ; /* check the end of string */
return 1 ;
}
2017-08-19 20:33:50 +00:00
static void printVersion ( void )
{
2020-06-08 12:06:37 +00:00
if ( g_displayLevel < DISPLAY_LEVEL_DEFAULT ) {
DISPLAYOUT ( " %s \n " , ZSTD_VERSION_STRING ) ;
return ;
}
2019-12-03 00:08:08 +00:00
DISPLAYOUT ( WELCOME_MESSAGE ) ;
if ( g_displayLevel > = 3 ) {
2017-08-19 20:33:50 +00:00
/* format support */
2019-12-03 00:08:08 +00: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 20:33:50 +00:00
}
2016-12-13 11:18:07 +00:00
2018-12-19 21:26:27 +00:00
/* Environment variables for parameter setting */
# define ENV_CLEVEL "ZSTD_CLEVEL"
2019-12-03 00:08:08 +00:00
/* pick up environment variable */
2018-12-20 01:56:45 +00:00
static int init_cLevel ( void ) {
2018-12-20 00:45:42 +00:00
const char * const env = getenv ( ENV_CLEVEL ) ;
2019-12-02 22:28:18 +00:00
if ( env ! = NULL ) {
const char * ptr = env ;
2018-12-19 21:26:27 +00:00
int sign = 1 ;
2018-12-20 00:45:42 +00:00
if ( * ptr = = ' - ' ) {
2018-12-19 21:26:27 +00:00
sign = - 1 ;
2018-12-20 00:45:42 +00:00
ptr + + ;
} else if ( * ptr = = ' + ' ) {
ptr + + ;
}
if ( ( * ptr > = ' 0 ' ) & & ( * ptr < = ' 9 ' ) ) {
unsigned absLevel ;
2019-04-10 17:03:06 +00:00
if ( readU32FromCharChecked ( & ptr , & absLevel ) ) {
2019-12-02 22:28:18 +00:00
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: numeric value too large \n " , ENV_CLEVEL , env ) ;
2018-12-20 00:45:42 +00:00
return ZSTDCLI_CLEVEL_DEFAULT ;
} else if ( * ptr = = 0 ) {
2019-10-17 22:27:25 +00:00
return sign * ( int ) absLevel ;
2019-12-02 22:28:18 +00:00
} }
2018-12-19 21:26:27 +00:00
2019-12-02 22:28:18 +00:00
DISPLAYLEVEL ( 2 , " Ignore environment variable setting %s=%s: not a valid integer value \n " , ENV_CLEVEL , env ) ;
2018-12-19 21:26:27 +00:00
}
return ZSTDCLI_CLEVEL_DEFAULT ;
}
2020-07-21 00:41:32 +00: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 19:46:36 +00:00
}
2020-01-31 18:47:17 +00:00
2020-07-17 19:46:36 +00:00
# define ZSTD_NB_STRATEGIES 9
2020-01-31 00:52:07 +00:00
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 " } ;
2017-06-05 21:45:31 +00:00
typedef enum { zom_compress , zom_decompress , zom_test , zom_bench , zom_train , zom_list } zstd_operation_mode ;
2016-05-29 03:16:05 +00:00
# define CLEAN_RETURN(i) { operationResult = (i); goto _end; }
2018-09-25 01:16:08 +00:00
# ifdef ZSTD_NOCOMPRESS
/* symbols from compression library are not defined and should not be invoked */
2019-12-02 22:28:18 +00:00
# define MINCLEVEL -99
2018-09-25 01:16:08 +00:00
# define MAXCLEVEL 22
# else
# define MINCLEVEL ZSTD_minCLevel()
# define MAXCLEVEL ZSTD_maxCLevel()
# endif
2019-12-02 22:28:18 +00:00
int main ( int const argCount , const char * argv [ ] )
2016-05-29 03:16:05 +00:00
{
int argNb ,
2018-02-13 22:56:35 +00:00
followLinks = 0 ,
forceStdout = 0 ,
2018-02-09 23:53:27 +00:00
ldmFlag = 0 ,
2018-02-13 22:56:35 +00:00
main_pause = 0 ,
nbWorkers = 0 ,
2018-08-12 03:48:06 +00:00
adapt = 0 ,
2018-09-25 01:16:08 +00:00
adaptMin = MINCLEVEL ,
adaptMax = MAXCLEVEL ,
2018-11-13 03:59:42 +00:00
rsyncable = 0 ,
2018-02-13 22:56:35 +00:00
nextArgumentsAreFiles = 0 ,
operationResult = 0 ,
2017-11-17 08:22:55 +00:00
separateFiles = 0 ,
2018-02-09 23:53:27 +00:00
setRealTimePrio = 0 ,
2018-02-13 22:56:35 +00:00
singleThread = 0 ,
2020-01-30 22:12:03 +00:00
showDefaultCParams = 0 ,
2020-03-09 18:07:29 +00:00
ultra = 0 ,
2020-03-09 19:12:52 +00:00
contentSize = 1 ;
2018-06-19 17:58:22 +00:00
double compressibility = 0.5 ;
2017-01-20 00:59:56 +00:00
unsigned bench_nbSeconds = 3 ; /* would be better if this value was synchronized from bench */
size_t blockSize = 0 ;
2019-01-23 01:31:13 +00:00
FIO_prefs_t * const prefs = FIO_createPreferences ( ) ;
2016-10-28 20:58:31 +00:00
zstd_operation_mode operation = zom_compress ;
2016-12-13 11:18:07 +00:00
ZSTD_compressionParameters compressionParams ;
2019-12-03 00:08:08 +00:00
int cLevel = init_cLevel ( ) ;
2019-12-02 22:28:18 +00:00
int cLevelLast = MINCLEVEL - 1 ; /* lower than minimum */
2016-05-29 03:16:05 +00:00
unsigned recursive = 0 ;
2016-10-14 20:13:13 +00:00
unsigned memLimit = 0 ;
2019-11-06 01:02:43 +00:00
FileNamesTable * filenames = UTIL_allocateFileNamesTable ( ( size_t ) argCount ) ; /* argCount >= 1 */
FileNamesTable * file_of_names = UTIL_allocateFileNamesTable ( ( size_t ) argCount ) ; /* argCount >= 1 */
2016-05-29 03:16:05 +00:00
const char * programName = argv [ 0 ] ;
const char * outFileName = NULL ;
2019-09-05 23:03:35 +00:00
const char * outDirName = NULL ;
2020-06-20 02:35:51 +00:00
const char * outMirroredDirName = NULL ;
2016-05-29 03:16:05 +00:00
const char * dictFileName = NULL ;
2020-01-10 22:25:24 +00:00
const char * patchFromDictFileName = NULL ;
2017-02-08 16:37:14 +00:00
const char * suffix = ZSTD_EXTENSION ;
2016-05-29 03:16:05 +00:00
unsigned maxDictSize = g_defaultMaxDictSize ;
2016-05-30 19:18:52 +00:00
unsigned dictID = 0 ;
2019-08-16 06:57:55 +00:00
size_t streamSrcSize = 0 ;
2019-06-24 20:40:52 +00:00
size_t targetCBlockSize = 0 ;
2019-08-19 15:52:08 +00:00
size_t srcSizeHint = 0 ;
2016-07-27 13:09:11 +00:00
int dictCLevel = g_defaultDictCLevel ;
2016-05-29 03:16:05 +00:00
unsigned dictSelect = g_defaultSelectivityLevel ;
2017-01-01 05:08:24 +00:00
# ifndef ZSTD_NODICT
2017-06-27 04:07:14 +00:00
ZDICT_cover_params_t coverParams = defaultCoverParams ( ) ;
2018-08-23 19:06:20 +00:00
ZDICT_fastCover_params_t fastCoverParams = defaultFastCoverParams ( ) ;
dictType dict = fastCover ;
2017-01-01 05:08:24 +00:00
# endif
2018-08-03 14:54:29 +00:00
# ifndef ZSTD_NOBENCH
BMK_advancedParams_t benchParams = BMK_initAdvancedParams ( ) ;
# endif
2019-02-15 23:24:55 +00:00
ZSTD_literalCompressionMode_e literalCompressionMode = ZSTD_lcm_auto ;
2016-05-29 03:16:05 +00:00
2017-10-01 19:10:26 +00:00
2016-05-29 03:16:05 +00:00
/* init */
2016-06-04 23:05:01 +00:00
( void ) recursive ; ( void ) cLevelLast ; /* not used when ZSTD_NOBENCH set */
2020-01-10 22:25:24 +00:00
( void ) memLimit ;
2019-12-02 22:28:18 +00:00
assert ( argCount > = 1 ) ;
2019-11-06 01:02:43 +00:00
if ( ( filenames = = NULL ) | | ( file_of_names = = NULL ) ) { DISPLAY ( " zstd: allocation error \n " ) ; exit ( 1 ) ; }
2017-03-25 00:06:09 +00:00
programName = lastNameFromPath ( programName ) ;
2018-02-13 22:56:35 +00:00
# ifdef ZSTD_MULTITHREAD
nbWorkers = 1 ;
# endif
2016-05-29 03:16:05 +00:00
/* preset behaviors */
2018-06-30 00:10:56 +00:00
if ( exeNameMatch ( programName , ZSTD_ZSTDMT ) ) nbWorkers = 0 , singleThread = 0 ;
2017-03-25 00:06:09 +00:00
if ( exeNameMatch ( programName , ZSTD_UNZSTD ) ) operation = zom_decompress ;
2019-04-27 23:06:29 +00: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-23 01:31:13 +00: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 23:06:29 +00: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-23 01:31:13 +00: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 11:18:07 +00:00
memset ( & compressionParams , 0 , sizeof ( compressionParams ) ) ;
2016-05-29 03:16:05 +00:00
2018-09-07 01:46:52 +00:00
/* init crash handler */
2018-09-11 18:56:50 +00:00
FIO_addAbortHandler ( ) ;
2018-09-07 01:46:52 +00:00
2016-05-29 03:16:05 +00:00
/* command switches */
2016-10-14 21:07:11 +00:00
for ( argNb = 1 ; argNb < argCount ; argNb + + ) {
2016-05-29 03:16:05 +00:00
const char * argument = argv [ argNb ] ;
2019-11-06 01:02:43 +00: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-29 03:16:05 +00:00
2019-11-06 01:02:43 +00: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 ; }
if ( ! strcmp ( argument , " --force " ) ) { FIO_overwriteMode ( prefs ) ; forceStdout = 1 ; followLinks = 1 ; continue ; }
2019-12-03 00:08:08 +00:00
if ( ! strcmp ( argument , " --version " ) ) { printVersion ( ) ; CLEAN_RETURN ( 0 ) ; }
if ( ! strcmp ( argument , " --help " ) ) { usage_advanced ( programName ) ; CLEAN_RETURN ( 0 ) ; }
2019-11-06 01:02:43 +00: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 22:12:03 +00:00
if ( ! strcmp ( argument , " --show-default-cparams " ) ) { showDefaultCParams = 1 ; continue ; }
2020-03-09 19:19:05 +00:00
if ( ! strcmp ( argument , " --content-size " ) ) { contentSize = 1 ; continue ; }
2020-03-09 19:12:52 +00:00
if ( ! strcmp ( argument , " --no-content-size " ) ) { contentSize = 0 ; continue ; }
2019-11-06 01:02:43 +00:00
if ( ! strcmp ( argument , " --adapt " ) ) { adapt = 1 ; continue ; }
2019-12-03 00:08:08 +00:00
if ( longCommandWArg ( & argument , " --adapt= " ) ) { adapt = 1 ; if ( ! parseAdaptParameters ( argument , & adaptMin , & adaptMax ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; } continue ; }
2019-11-06 01:02:43 +00: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-02 00:49:20 +00:00
# ifdef ZSTD_GZCOMPRESS
2019-11-06 01:02:43 +00:00
if ( ! strcmp ( argument , " --format=gzip " ) ) { suffix = GZ_EXTENSION ; FIO_setCompressionType ( prefs , FIO_gzipCompression ) ; continue ; }
2017-03-02 00:49:20 +00:00
# endif
2017-03-14 01:11:07 +00:00
# ifdef ZSTD_LZMACOMPRESS
2019-11-06 01:02:43 +00: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-14 01:11:07 +00:00
# endif
2017-04-24 23:48:25 +00:00
# ifdef ZSTD_LZ4COMPRESS
2019-11-06 01:02:43 +00:00
if ( ! strcmp ( argument , " --format=lz4 " ) ) { suffix = LZ4_EXTENSION ; FIO_setCompressionType ( prefs , FIO_lz4Compression ) ; continue ; }
2017-04-24 23:48:25 +00:00
# endif
2019-11-06 01:02:43 +00:00
if ( ! strcmp ( argument , " --rsyncable " ) ) { rsyncable = 1 ; continue ; }
if ( ! strcmp ( argument , " --compress-literals " ) ) { literalCompressionMode = ZSTD_lcm_huffman ; continue ; }
if ( ! strcmp ( argument , " --no-compress-literals " ) ) { literalCompressionMode = ZSTD_lcm_uncompressed ; continue ; }
if ( ! strcmp ( argument , " --no-progress " ) ) { FIO_setNoProgress ( 1 ) ; continue ; }
if ( ! strcmp ( argument , " --exclude-compressed " ) ) { FIO_setExcludeCompressedFile ( prefs , 1 ) ; continue ; }
2020-07-21 00:41:32 +00:00
2019-11-06 01:02:43 +00:00
/* long commands with arguments */
2017-03-02 00:49:20 +00:00
# ifndef ZSTD_NODICT
2019-11-06 01:02:43 +00: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-03 00:08:08 +00:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseCoverParameters ( argument , & coverParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-06 01:02:43 +00: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-03 00:08:08 +00:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseFastCoverParameters ( argument , & fastCoverParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-06 01:02:43 +00: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-03 00:08:08 +00:00
else if ( * argument + + ! = ' = ' ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
else if ( ! parseLegacyParameters ( argument , & dictSelect ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; }
2019-11-06 01:02:43 +00:00
continue ;
}
2017-01-01 05:08:24 +00:00
# endif
2020-07-21 00:41:32 +00: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 19:29:58 +00:00
if ( longCommandWArg ( & argument , " --block-size= " ) ) { blockSize = readSizeTFromChar ( & argument ) ; continue ; }
2020-07-21 00:41:32 +00:00
if ( longCommandWArg ( & argument , " --maxdict " ) ) { NEXT_UINT32 ( maxDictSize ) ; continue ; }
if ( longCommandWArg ( & argument , " --dictID " ) ) { NEXT_UINT32 ( dictID ) ; continue ; }
2019-12-03 00:08:08 +00:00
if ( longCommandWArg ( & argument , " --zstd= " ) ) { if ( ! parseCompressionParameters ( argument , & compressionParams ) ) { badusage ( programName ) ; CLEAN_RETURN ( 1 ) ; } continue ; }
2020-02-20 19:29:58 +00: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-21 00:41:32 +00:00
if ( longCommandWArg ( & argument , " --output-dir-flat " ) ) { NEXT_FIELD ( outDirName ) ; continue ; }
# ifdef UTIL_HAS_MIRRORFILELIST
if ( longCommandWArg ( & argument , " --output-dir-mirror " ) ) { NEXT_FIELD ( outMirroredDirName ) ; continue ; }
# endif
if ( longCommandWArg ( & argument , " --patch-from " ) ) { NEXT_FIELD ( patchFromDictFileName ) ; continue ; }
2019-11-06 01:02:43 +00: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 */
2019-12-03 00:08:08 +00:00
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
2017-09-22 21:04:39 +00:00
}
2019-11-06 01:02:43 +00:00
/* Only set windowLog if not already set by --zstd */
if ( compressionParams . windowLog = = 0 )
compressionParams . windowLog = ldmWindowLog ;
continue ;
}
2018-09-23 00:21:39 +00:00
# ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */
2019-11-06 01:02:43 +00: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-03 00:08:08 +00:00
dictCLevel = cLevel = - ( int ) fastLevel ;
2018-03-12 02:56:48 +00:00
} else {
2019-12-03 00:08:08 +00:00
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
2018-03-12 02:56:48 +00:00
}
2019-11-06 01:02:43 +00:00
} else if ( * argument ! = 0 ) {
/* Invalid character following --fast */
2019-12-03 00:08:08 +00:00
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
2019-11-06 01:02:43 +00:00
} else {
cLevel = - 1 ; /* default for --fast */
2018-03-12 02:56:48 +00:00
}
2019-11-06 01:02:43 +00:00
continue ;
}
2018-09-23 00:21:39 +00:00
# endif
2019-10-15 06:49:13 +00:00
2020-07-21 00:41:32 +00:00
if ( longCommandWArg ( & argument , " --filelist " ) ) {
const char * listName ;
NEXT_FIELD ( listName ) ;
UTIL_refFilename ( file_of_names , listName ) ;
2019-11-06 01:02:43 +00:00
continue ;
}
2019-10-15 06:49:13 +00:00
2019-11-06 01:02:43 +00:00
/* fall-through, will trigger bad_usage() later on */
}
2019-10-15 06:49:13 +00:00
2019-11-06 01:02:43 +00:00
argument + + ;
while ( argument [ 0 ] ! = 0 ) {
2020-07-17 20:09:23 +00:00
2016-09-01 22:05:57 +00:00
# ifndef ZSTD_NOCOMPRESS
2019-11-06 01:02:43 +00:00
/* compression Level */
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
dictCLevel = cLevel = ( int ) readU32FromChar ( & argument ) ;
continue ;
}
2016-09-01 22:05:57 +00:00
# endif
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
switch ( argument [ 0 ] )
{
/* Display help */
2019-12-03 00:08:08 +00:00
case ' V ' : printVersion ( ) ; CLEAN_RETURN ( 0 ) ; /* Version Only */
2019-11-06 01:02:43 +00:00
case ' H ' :
2019-12-03 00:08:08 +00:00
case ' h ' : usage_advanced ( programName ) ; CLEAN_RETURN ( 0 ) ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Compress */
case ' z ' : operation = zom_compress ; argument + + ; break ;
2016-10-28 20:58:31 +00:00
2019-11-06 01:02:43 +00:00
/* Decoding */
case ' d ' :
2016-12-07 01:56:20 +00:00
# ifndef ZSTD_NOBENCH
2019-11-06 01:02:43 +00:00
benchParams . mode = BMK_decodeOnly ;
if ( operation = = zom_bench ) { argument + + ; break ; } /* benchmark decode (hidden option) */
2016-12-07 01:56:20 +00:00
# endif
2019-11-06 01:02:43 +00:00
operation = zom_decompress ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Force stdout, even if stdout==console */
case ' c ' : forceStdout = 1 ; outFileName = stdoutmark ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Use file content as dictionary */
2020-07-21 00:41:32 +00:00
case ' D ' : argument + + ; NEXT_FIELD ( dictFileName ) ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Overwrite */
case ' f ' : FIO_overwriteMode ( prefs ) ; forceStdout = 1 ; followLinks = 1 ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Verbose mode */
case ' v ' : g_displayLevel + + ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Quiet mode */
case ' q ' : g_displayLevel - - ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* keep source file (default) */
case ' k ' : FIO_setRemoveSrcFile ( prefs , 0 ) ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Checksum */
case ' C ' : FIO_setChecksumFlag ( prefs , 2 ) ; argument + + ; break ;
2016-06-02 15:05:50 +00:00
2019-11-06 01:02:43 +00:00
/* test compressed file */
case ' t ' : operation = zom_test ; argument + + ; break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* destination file name */
2020-07-21 00:41:32 +00:00
case ' o ' : argument + + ; NEXT_FIELD ( outFileName ) ; break ;
2019-10-17 22:27:25 +00:00
2020-01-10 22:25:24 +00:00
/* limit memory */
2019-11-06 01:02:43 +00:00
case ' M ' :
argument + + ;
memLimit = readU32FromChar ( & argument ) ;
break ;
case ' l ' : operation = zom_list ; argument + + ; break ;
2016-09-13 15:50:08 +00:00
# ifdef UTIL_HAS_CREATEFILELIST
2019-11-06 01:02:43 +00:00
/* recursive */
case ' r ' : recursive = 1 ; argument + + ; break ;
2016-09-13 15:50:08 +00:00
# endif
2016-05-29 03:16:05 +00:00
2016-09-01 22:05:57 +00:00
# ifndef ZSTD_NOBENCH
2019-11-06 01:02:43 +00: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 08:22:55 +00:00
2017-01-20 00:59:56 +00:00
# endif /* ZSTD_NOBENCH */
2019-11-06 01:02:43 +00:00
/* nb of threads (hidden option) */
case ' T ' :
argument + + ;
nbWorkers = ( int ) readU32FromChar ( & argument ) ;
break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Dictionary Selection level */
case ' s ' :
argument + + ;
dictSelect = readU32FromChar ( & argument ) ;
break ;
2016-05-29 03:16:05 +00:00
2019-11-06 01:02:43 +00:00
/* Pause at the end (-p) or set an additional param (-p#) (hidden option) */
case ' p ' : argument + + ;
2016-09-01 22:05:57 +00:00
# ifndef ZSTD_NOBENCH
2019-11-06 01:02:43 +00:00
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
benchParams . additionalParam = ( int ) readU32FromChar ( & argument ) ;
} else
2016-09-01 22:05:57 +00:00
# endif
2019-11-06 01:02:43 +00:00
main_pause = 1 ;
2018-06-19 17:58:22 +00:00
break ;
2019-11-06 01:02:43 +00:00
/* Select compressibility of synthetic sample */
case ' P ' :
2020-07-21 00:41:32 +00:00
argument + + ;
2019-11-06 01:02:43 +00:00
compressibility = ( double ) readU32FromChar ( & argument ) / 100 ;
2020-07-21 00:41:32 +00:00
break ;
2016-07-04 16:16:16 +00:00
2019-11-06 01:02:43 +00:00
/* unknown command */
2019-12-03 00:08:08 +00:00
default : badusage ( programName ) ; CLEAN_RETURN ( 1 ) ;
2019-11-06 01:02:43 +00:00
}
2016-07-04 16:16:16 +00:00
}
2019-11-06 01:02:43 +00:00
continue ;
} /* if (argument[0]=='-') */
/* none of the above : add filename to list */
UTIL_refFilename ( filenames , argument ) ;
2016-05-29 03:16:05 +00:00
}
/* Welcome message (if verbose) */
DISPLAYLEVEL ( 3 , WELCOME_MESSAGE ) ;
2018-02-13 22:56:35 +00:00
# ifdef ZSTD_MULTITHREAD
if ( ( nbWorkers = = 0 ) & & ( ! singleThread ) ) {
2018-02-02 03:29:30 +00:00
/* automatically set # workers based on # of reported cpus */
nbWorkers = UTIL_countPhysicalCores ( ) ;
DISPLAYLEVEL ( 3 , " Note: %d physical core(s) detected \n " , nbWorkers ) ;
2017-04-13 19:28:28 +00:00
}
2018-06-26 08:22:45 +00:00
# else
2018-06-30 00:10:56 +00:00
( void ) singleThread ; ( void ) nbWorkers ;
2018-02-13 22:56:35 +00:00
# endif
2017-03-23 18:52:09 +00:00
2018-06-26 08:22:45 +00:00
# ifdef UTIL_HAS_CREATEFILELIST
2017-03-23 19:09:35 +00:00
g_utilDisplayLevel = g_displayLevel ;
2017-03-23 18:52:09 +00:00
if ( ! followLinks ) {
2019-11-06 01:02:43 +00:00
unsigned u , fileNamesNb ;
unsigned const nbFilenames = ( unsigned ) filenames - > tableSize ;
for ( u = 0 , fileNamesNb = 0 ; u < nbFilenames ; u + + ) {
2019-11-26 19:20:26 +00:00
if ( UTIL_isLink ( filenames - > fileNames [ u ] )
& & ! UTIL_isFIFO ( filenames - > fileNames [ u ] )
2019-10-25 21:06:50 +00:00
) {
2019-11-26 19:20:26 +00:00
DISPLAYLEVEL ( 2 , " Warning : %s is a symbolic link, ignoring \n " , filenames - > fileNames [ u ] ) ;
2017-03-23 18:52:09 +00:00
} else {
2019-11-06 01:02:43 +00:00
filenames - > fileNames [ fileNamesNb + + ] = filenames - > fileNames [ u ] ;
2019-10-26 01:16:45 +00:00
} }
2019-11-06 01:02:43 +00:00
if ( fileNamesNb = = 0 & & nbFilenames > 0 ) /* all names are eliminated */
2019-02-11 23:07:32 +00:00
CLEAN_RETURN ( 1 ) ;
2019-11-06 01:02:43 +00: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 17:10:05 +00:00
filenames = UTIL_mergeFileNamesTable ( filenames , fnt ) ;
2019-11-06 01:02:43 +00:00
}
2017-03-23 18:52:09 +00:00
}
2019-11-06 01:02:43 +00:00
2016-09-21 10:24:43 +00:00
if ( recursive ) { /* at this stage, filenameTable is a list of paths, which can contain both files and directories */
2019-11-06 17:10:05 +00:00
UTIL_expandFNT ( & filenames , followLinks ) ;
2019-11-06 01:02:43 +00:00
}
2018-06-26 08:22:45 +00:00
# else
( void ) followLinks ;
2016-05-29 03:16:05 +00:00
# endif
2017-08-19 01:30:41 +00:00
2017-06-16 00:46:49 +00:00
if ( operation = = zom_list ) {
2017-08-19 01:30:41 +00:00
# ifndef ZSTD_NODECOMPRESS
2019-11-06 01:02:43 +00:00
int const ret = FIO_listMultipleFiles ( ( unsigned ) filenames - > tableSize , filenames - > fileNames , g_displayLevel ) ;
2017-06-20 19:43:10 +00:00
CLEAN_RETURN ( ret ) ;
2017-08-19 01:30:41 +00:00
# else
DISPLAY ( " file information is not supported \n " ) ;
CLEAN_RETURN ( 1 ) ;
# endif
2017-06-05 21:45:31 +00:00
}
2017-08-19 01:30:41 +00:00
2016-05-29 03:16:05 +00:00
/* Check if benchmark is selected */
2016-10-28 20:58:31 +00:00
if ( operation = = zom_bench ) {
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NOBENCH
2018-08-03 14:54:29 +00:00
benchParams . blockSize = blockSize ;
benchParams . nbWorkers = nbWorkers ;
2019-10-17 22:27:25 +00:00
benchParams . realTime = ( unsigned ) setRealTimePrio ;
2018-08-03 14:54:29 +00:00
benchParams . nbSeconds = bench_nbSeconds ;
benchParams . ldmFlag = ldmFlag ;
2019-10-17 22:27:25 +00:00
benchParams . ldmMinMatch = ( int ) g_ldmMinMatch ;
benchParams . ldmHashLog = ( int ) g_ldmHashLog ;
2017-09-03 04:10:36 +00:00
if ( g_ldmBucketSizeLog ! = LDM_PARAM_DEFAULT ) {
2019-10-17 22:27:25 +00:00
benchParams . ldmBucketSizeLog = ( int ) g_ldmBucketSizeLog ;
2017-09-03 04:10:36 +00:00
}
2018-11-21 22:36:57 +00:00
if ( g_ldmHashRateLog ! = LDM_PARAM_DEFAULT ) {
2019-10-17 22:27:25 +00:00
benchParams . ldmHashRateLog = ( int ) g_ldmHashRateLog ;
2017-09-03 04:10:36 +00:00
}
2019-02-15 23:24:55 +00:00
benchParams . literalCompressionMode = literalCompressionMode ;
2018-06-15 20:21:08 +00:00
2018-06-18 22:06:31 +00:00
if ( cLevel > ZSTD_maxCLevel ( ) ) cLevel = ZSTD_maxCLevel ( ) ;
if ( cLevelLast > ZSTD_maxCLevel ( ) ) cLevelLast = ZSTD_maxCLevel ( ) ;
if ( cLevelLast < cLevel ) cLevelLast = cLevel ;
2018-07-10 01:24:07 +00:00
if ( cLevelLast > cLevel )
2018-08-28 18:21:09 +00:00
DISPLAYLEVEL ( 3 , " Benchmarking levels from %d to %d \n " , cLevel , cLevelLast ) ;
2019-11-06 01:02:43 +00:00
if ( filenames - > tableSize > 0 ) {
2018-06-19 17:58:22 +00:00
if ( separateFiles ) {
unsigned i ;
2019-11-06 01:02:43 +00:00
for ( i = 0 ; i < filenames - > tableSize ; i + + ) {
2018-06-19 17:58:22 +00:00
int c ;
2019-11-06 01:02:43 +00:00
DISPLAYLEVEL ( 3 , " Benchmarking %s \n " , filenames - > fileNames [ i ] ) ;
2018-06-19 17:58:22 +00:00
for ( c = cLevel ; c < = cLevelLast ; c + + ) {
2019-11-06 01:02:43 +00:00
BMK_benchFilesAdvanced ( & filenames - > fileNames [ i ] , 1 , dictFileName , c , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 23:36:59 +00:00
} }
2018-06-19 17:58:22 +00:00
} else {
for ( ; cLevel < = cLevelLast ; cLevel + + ) {
2019-11-06 01:02:43 +00:00
BMK_benchFilesAdvanced ( filenames - > fileNames , ( unsigned ) filenames - > tableSize , dictFileName , cLevel , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 23:36:59 +00:00
} }
2018-06-18 22:06:31 +00:00
} else {
for ( ; cLevel < = cLevelLast ; cLevel + + ) {
2018-08-03 14:54:29 +00:00
BMK_syntheticTest ( cLevel , compressibility , & compressionParams , g_displayLevel , & benchParams ) ;
2019-10-25 23:36:59 +00:00
} }
2018-06-15 20:21:08 +00:00
2017-12-02 01:42:46 +00:00
# else
2018-08-03 15:30:01 +00:00
( void ) bench_nbSeconds ; ( void ) blockSize ; ( void ) setRealTimePrio ; ( void ) separateFiles ; ( void ) compressibility ;
2016-05-29 03:16:05 +00:00
# endif
goto _end ;
}
/* Check if dictionary builder is selected */
2016-10-28 20:58:31 +00:00
if ( operation = = zom_train ) {
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NODICT
2017-06-27 04:07:14 +00:00
ZDICT_params_t zParams ;
zParams . compressionLevel = dictCLevel ;
2019-10-17 22:27:25 +00:00
zParams . notificationLevel = ( unsigned ) g_displayLevel ;
2017-06-27 04:07:14 +00:00
zParams . dictID = dictID ;
2018-08-23 19:06:20 +00:00
if ( dict = = cover ) {
2017-05-02 06:40:20 +00:00
int const optimize = ! coverParams . k | | ! coverParams . d ;
2019-10-17 22:27:25 +00:00
coverParams . nbThreads = ( unsigned ) nbWorkers ;
2017-06-27 04:07:14 +00:00
coverParams . zParams = zParams ;
2019-11-06 01:02:43 +00:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( unsigned ) filenames - > tableSize , blockSize , NULL , & coverParams , NULL , optimize ) ;
2018-08-23 19:06:20 +00:00
} else if ( dict = = fastCover ) {
int const optimize = ! fastCoverParams . k | | ! fastCoverParams . d ;
2019-10-17 22:27:25 +00:00
fastCoverParams . nbThreads = ( unsigned ) nbWorkers ;
2018-08-23 19:06:20 +00:00
fastCoverParams . zParams = zParams ;
2019-11-06 01:02:43 +00:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( unsigned ) filenames - > tableSize , blockSize , NULL , NULL , & fastCoverParams , optimize ) ;
2017-01-01 05:08:24 +00:00
} else {
2017-06-27 04:07:14 +00:00
ZDICT_legacy_params_t dictParams ;
2017-01-01 05:08:24 +00:00
memset ( & dictParams , 0 , sizeof ( dictParams ) ) ;
dictParams . selectivityLevel = dictSelect ;
2017-06-27 04:07:14 +00:00
dictParams . zParams = zParams ;
2019-11-06 01:02:43 +00:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenames - > fileNames , ( unsigned ) filenames - > tableSize , blockSize , & dictParams , NULL , NULL , 0 ) ;
2017-01-01 05:08:24 +00:00
}
2018-09-24 07:52:19 +00: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-29 03:16:05 +00:00
# endif
goto _end ;
}
2017-07-18 21:45:49 +00:00
# ifndef ZSTD_NODECOMPRESS
2019-10-17 23:09:53 +00:00
if ( operation = = zom_test ) { FIO_setTestMode ( prefs , 1 ) ; outFileName = nulmark ; FIO_setRemoveSrcFile ( prefs , 0 ) ; } /* test mode */
2017-07-18 21:45:49 +00:00
# endif
2016-05-29 03:16:05 +00:00
/* No input filename ==> use stdin and stdout */
2019-11-06 01:02:43 +00:00
if ( filenames - > tableSize = = 0 ) UTIL_refFilename ( filenames , stdinmark ) ;
if ( ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark ) & & ! outFileName )
2018-03-12 02:56:48 +00:00
outFileName = stdoutmark ; /* when input is stdin, default output is stdout */
2016-05-29 03:16:05 +00:00
/* Check if input/output defined as console; trigger an error in this case */
2019-12-03 00:08:08 +00:00
if ( ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark ) & & IS_CONSOLE ( stdin ) ) {
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
}
2018-03-12 02:56:48 +00:00
if ( outFileName & & ! strcmp ( outFileName , stdoutmark )
& & IS_CONSOLE ( stdout )
2019-11-06 01:02:43 +00:00
& & ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark )
2018-03-12 02:56:48 +00:00
& & ! forceStdout
2019-12-03 00:08:08 +00:00
& & operation ! = zom_decompress ) {
badusage ( programName ) ;
CLEAN_RETURN ( 1 ) ;
}
2016-05-29 03:16:05 +00:00
2016-10-05 09:56:22 +00:00
# ifndef ZSTD_NOCOMPRESS
2016-08-12 16:04:15 +00: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 09:56:22 +00:00
# endif
2016-08-12 16:04:15 +00:00
2020-01-30 22:12:03 +00: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 22:25:24 +00: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 20:58:53 +00:00
if ( patchFromDictFileName ! = NULL & & filenames - > tableSize > 1 ) {
DISPLAY ( " error : can't use --patch-from=# on multiple files \n " ) ;
CLEAN_RETURN ( 1 ) ;
}
2017-01-19 21:46:30 +00:00
/* No status message in pipe mode (stdin - stdout) or multi-files mode */
2019-11-06 01:02:43 +00:00
if ( ! strcmp ( filenames - > fileNames [ 0 ] , stdinmark ) & & outFileName & & ! strcmp ( outFileName , stdoutmark ) & & ( g_displayLevel = = 2 ) ) g_displayLevel = 1 ;
if ( ( filenames - > tableSize > 1 ) & ( g_displayLevel = = 2 ) ) g_displayLevel = 1 ;
2016-05-29 03:16:05 +00:00
/* IO Stream/File */
2017-03-23 18:13:52 +00:00
FIO_setNotificationLevel ( g_displayLevel ) ;
2020-01-10 22:25:24 +00: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 20:58:53 +00:00
if ( patchFromDictFileName ! = NULL )
dictFileName = patchFromDictFileName ;
2020-01-10 22:25:24 +00:00
FIO_setMemLimit ( prefs , memLimit ) ;
2016-10-28 20:58:31 +00:00
if ( operation = = zom_compress ) {
2016-09-21 10:24:43 +00:00
# ifndef ZSTD_NOCOMPRESS
2020-03-09 19:12:52 +00:00
FIO_setContentSize ( prefs , contentSize ) ;
2019-01-23 01:31:13 +00:00
FIO_setNbWorkers ( prefs , nbWorkers ) ;
2019-10-17 22:27:25 +00: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 ) ;
2019-01-23 01:31:13 +00:00
FIO_setAdaptMin ( prefs , adaptMin ) ;
FIO_setAdaptMax ( prefs , adaptMax ) ;
FIO_setRsyncable ( prefs , rsyncable ) ;
2019-08-16 06:57:55 +00:00
FIO_setStreamSrcSize ( prefs , streamSrcSize ) ;
2019-06-24 20:40:52 +00:00
FIO_setTargetCBlockSize ( prefs , targetCBlockSize ) ;
2019-08-19 15:52:08 +00:00
FIO_setSrcSizeHint ( prefs , srcSizeHint ) ;
2019-02-15 23:24:55 +00:00
FIO_setLiteralCompressionMode ( prefs , literalCompressionMode ) ;
2018-09-25 01:16:08 +00:00
if ( adaptMin > cLevel ) cLevel = adaptMin ;
if ( adaptMax < cLevel ) cLevel = adaptMax ;
2017-09-01 21:52:51 +00:00
2020-02-03 17:52:39 +00:00
/* Compare strategies constant with the ground truth */
{ ZSTD_bounds strategyBounds = ZSTD_cParam_getBounds ( ZSTD_c_strategy ) ;
2020-05-08 20:42:15 +00:00
assert ( ZSTD_NB_STRATEGIES = = strategyBounds . upperBound ) ;
( void ) strategyBounds ; }
2020-01-31 18:47:17 +00:00
2020-01-30 22:12:03 +00:00
if ( showDefaultCParams ) {
size_t fileNb ;
for ( fileNb = 0 ; fileNb < ( size_t ) filenames - > tableSize ; fileNb + + ) {
2020-01-31 01:16:02 +00:00
unsigned long long fileSize = UTIL_getFileSize ( filenames - > fileNames [ fileNb ] ) ;
2020-01-31 00:52:07 +00:00
const size_t dictSize = dictFileName ! = NULL ? ( size_t ) UTIL_getFileSize ( dictFileName ) : 0 ;
2020-01-31 01:05:33 +00:00
const ZSTD_compressionParameters cParams = ZSTD_getCParams ( cLevel , fileSize , dictSize ) ;
2020-01-31 01:16:02 +00:00
if ( fileSize ! = UTIL_FILESIZE_UNKNOWN ) DISPLAY ( " %s (%u bytes) \n " , filenames - > fileNames [ fileNb ] , ( unsigned ) fileSize ) ;
2020-01-31 00:52:07 +00:00
else DISPLAY ( " %s (src size unknown) \ n " , filenames->fileNames[fileNb]) ;
2020-02-06 21:51:43 +00:00
DISPLAY ( " - windowLog : %u \n " , cParams . windowLog ) ;
DISPLAY ( " - chainLog : %u \n " , cParams . chainLog ) ;
2020-02-27 21:56:56 +00:00
DISPLAY ( " - hashLog : %u \n " , cParams . hashLog ) ;
2020-02-06 21:51:43 +00:00
DISPLAY ( " - searchLog : %u \n " , cParams . searchLog ) ;
DISPLAY ( " - minMatch : %u \n " , cParams . minMatch ) ;
DISPLAY ( " - targetLength : %u \n " , cParams . targetLength ) ;
2020-01-31 01:54:01 +00:00
assert ( cParams . strategy < ZSTD_NB_STRATEGIES + 1 ) ;
2020-02-06 21:51:43 +00:00
DISPLAY ( " - strategy : %s (%u) \n " , ZSTD_strategyMap [ ( int ) cParams . strategy ] , ( unsigned ) cParams . strategy ) ;
2020-01-30 22:12:03 +00:00
}
}
2019-11-06 01:02:43 +00:00
if ( ( filenames - > tableSize = = 1 ) & & outFileName )
operationResult = FIO_compressFilename ( prefs , outFileName , filenames - > fileNames [ 0 ] , dictFileName , cLevel , compressionParams ) ;
2016-05-29 03:16:05 +00:00
else
2020-06-20 02:35:51 +00:00
operationResult = FIO_compressMultipleFilenames ( prefs , filenames - > fileNames , ( unsigned ) filenames - > tableSize , outMirroredDirName , outDirName , outFileName , suffix , dictFileName , cLevel , compressionParams ) ;
2016-09-21 10:24:43 +00:00
# else
2020-03-09 19:12:52 +00: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 ; /* not used when ZSTD_NOCOMPRESS set */
2018-09-24 23:56:45 +00:00
DISPLAY ( " Compression not supported \n " ) ;
2016-05-29 03:16:05 +00:00
# endif
2016-10-28 20:58:31 +00:00
} else { /* decompression or test */
2016-05-29 03:16:05 +00:00
# ifndef ZSTD_NODECOMPRESS
2019-11-06 01:02:43 +00:00
if ( filenames - > tableSize = = 1 & & outFileName ) {
operationResult = FIO_decompressFilename ( prefs , outFileName , filenames - > fileNames [ 0 ] , dictFileName ) ;
2019-10-25 23:36:59 +00:00
} else {
2020-06-20 02:35:51 +00:00
operationResult = FIO_decompressMultipleFilenames ( prefs , filenames - > fileNames , ( unsigned ) filenames - > tableSize , outMirroredDirName , outDirName , outFileName , dictFileName ) ;
2019-10-25 23:36:59 +00:00
}
2016-05-29 03:16:05 +00:00
# else
2018-09-24 23:56:45 +00:00
DISPLAY ( " Decompression not supported \n " ) ;
2016-05-29 03:16:05 +00:00
# endif
}
_end :
2019-01-23 01:31:13 +00:00
FIO_freePreferences ( prefs ) ;
2016-05-29 03:16:05 +00:00
if ( main_pause ) waitEnter ( ) ;
2019-11-06 01:02:43 +00:00
UTIL_freeFileNamesTable ( filenames ) ;
UTIL_freeFileNamesTable ( file_of_names ) ;
2019-10-26 01:16:45 +00:00
2016-05-29 03:16:05 +00:00
return operationResult ;
}