2017-08-18 16:52:05 -07:00
/*
2016-08-30 10:04:33 -07:00
* Copyright ( c ) 2016 - present , Yann Collet , Facebook , Inc .
* 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
2016-07-13 05:15:08 -07:00
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 */
2017-08-19 13:33:50 -07:00
# include <stdio.h> /* fprintf(), stdin, stdout, stderr */
2016-05-28 20:16:05 -07:00
# include <string.h> /* strcmp, strlen */
2016-07-04 09:16:16 -07:00
# include <errno.h> /* errno */
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
2016-11-03 03:38:01 -07:00
# include "bench.h" /* BMK_benchFiles, BMK_SetNbSeconds */
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
2016-06-04 10:47:02 -07:00
# define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel */
# include "zstd.h" /* ZSTD_VERSION_STRING */
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 ;
2017-09-02 21:10:36 -07:00
static U32 g_ldmHashEveryLog = LDM_PARAM_DEFAULT ;
static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT ;
2016-05-28 20:16:05 -07:00
/*-************************************
* Display Macros
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-03-23 11:13:52 -07:00
# define DISPLAY(...) fprintf(g_displayOut, __VA_ARGS__)
# 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 */
2017-03-23 11:13:52 -07:00
static FILE * g_displayOut ;
2016-05-28 20:16:05 -07:00
/*-************************************
* Command Line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int usage ( const char * programName )
{
2017-08-18 15:15:31 -07:00
DISPLAY ( " Usage : \n " ) ;
DISPLAY ( " %s [args] [FILE(s)] [-o file] \n " , programName ) ;
2016-05-28 20:16:05 -07:00
DISPLAY ( " \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " FILE : a filename \n " ) ;
2016-05-28 20:16:05 -07:00
DISPLAY ( " with no FILE, or when FILE is - , read standard input \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " Arguments : \n " ) ;
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOCOMPRESS
2018-01-24 04:59:44 -08:00
DISPLAY ( " -# : # 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
DISPLAY ( " -d : decompression \n " ) ;
# endif
DISPLAY ( " -D file: use `file` as Dictionary \n " ) ;
DISPLAY ( " -o file: result stored into `file` (only if 1 input file) \n " ) ;
2017-03-23 11:52:09 -07:00
DISPLAY ( " -f : overwrite output without prompting and (de)compress links \n " ) ;
2016-07-01 15:37:32 -07:00
DISPLAY ( " --rm : remove source file(s) after successful de/compression \n " ) ;
2016-07-03 15:42:58 -07:00
DISPLAY ( " -k : preserve source file(s) (default) \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " -h/-H : display help/long help and exit \n " ) ;
2016-05-28 20:16:05 -07:00
return 0 ;
}
static int usage_advanced ( const char * programName )
{
DISPLAY ( WELCOME_MESSAGE ) ;
usage ( programName ) ;
DISPLAY ( " \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " Advanced arguments : \n " ) ;
DISPLAY ( " -V : display Version number and exit \n " ) ;
2017-04-01 00:36:31 -07:00
DISPLAY ( " -v : verbose mode; specify multiple times to increase verbosity \n " ) ;
2016-05-28 20:16:05 -07:00
DISPLAY ( " -q : suppress warnings; specify twice to suppress errors too \n " ) ;
DISPLAY ( " -c : force write to standard output, even if it is the console \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " -l : print information about zstd compressed files \n " ) ;
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NOCOMPRESS
2016-08-12 09:04:15 -07:00
DISPLAY ( " --ultra : enable levels beyond %i, up to %i (requires more memory) \n " , ZSTDCLI_CLEVEL_MAX , ZSTD_maxCLevel ( ) ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " --long[=#] : enable long distance matching with given window log (default: %u) \n " , g_defaultMaxWindowLog ) ;
2017-01-19 16:59:56 -08:00
# ifdef ZSTD_MULTITHREAD
2018-02-09 15:53:27 -08:00
DISPLAY ( " -T# : spawns # compression threads (default: 1) \n " ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " -B# : select size of each job (default: 0==automatic) \n " ) ;
2017-04-01 00:36:31 -07:00
# endif
DISPLAY ( " --no-dictID : don't write dictID into header (dictionary compression) \n " ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " --[no-]check : integrity check (default: enabled) \n " ) ;
2017-04-01 00:36:31 -07:00
# endif
# ifdef UTIL_HAS_CREATEFILELIST
DISPLAY ( " -r : operate recursively on directories \n " ) ;
2017-01-19 16:59:56 -08:00
# endif
2017-02-08 06:17:55 -08:00
# ifdef ZSTD_GZCOMPRESS
2017-02-08 09:08:09 -08:00
DISPLAY ( " --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
DISPLAY ( " --format=xz : compress files to the .xz format \n " ) ;
DISPLAY ( " --format=lzma : compress files to the .lzma format \n " ) ;
# endif
2017-04-24 16:48:25 -07:00
# ifdef ZSTD_LZ4COMPRESS
DISPLAY ( " --format=lz4 : compress files to the .lz4 format \n " ) ;
# endif
2016-05-30 17:29:45 -07:00
# ifndef ZSTD_NODECOMPRESS
2016-06-02 08:05:50 -07:00
DISPLAY ( " --test : test compressed file integrity \n " ) ;
2017-03-31 15:16:43 -07:00
# if ZSTD_SPARSE_DEFAULT
2018-01-24 04:59:44 -08:00
DISPLAY ( " --[no-]sparse : sparse mode (default: enabled on file, disabled on stdout) \n " ) ;
2017-03-31 15:16:43 -07:00
# else
2018-01-24 04:59:44 -08:00
DISPLAY ( " --[no-]sparse : sparse mode (default: disabled) \n " ) ;
2017-03-31 15:16:43 -07:00
# endif
2016-05-30 17:29:45 -07:00
# endif
2016-10-14 13:13:13 -07:00
DISPLAY ( " -M# : Set a memory usage limit for decompression \n " ) ;
2016-09-16 09:52:52 -07:00
DISPLAY ( " -- : All arguments after \" -- \" are treated as files \n " ) ;
2016-05-28 20:16:05 -07:00
# ifndef ZSTD_NODICT
DISPLAY ( " \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " Dictionary builder : \n " ) ;
2016-06-09 13:59:51 -07:00
DISPLAY ( " --train ## : create a dictionary from a training set of files \n " ) ;
2017-05-01 23:40:20 -07:00
DISPLAY ( " --train-cover[=k=#,d=#,steps=#] : use the cover algorithm with optional args \n " ) ;
DISPLAY ( " --train-legacy[=s=#] : use the legacy algorithm with selectivity (default: %u) \n " , g_defaultSelectivityLevel ) ;
2016-06-09 13:59:51 -07:00
DISPLAY ( " -o file : `file` is dictionary name (default: %s) \n " , g_defaultDictName ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " --maxdict=# : limit dictionary to specified size (default: %u) \n " , g_defaultMaxDictSize ) ;
2017-03-24 16:04:29 -07:00
DISPLAY ( " --dictID=# : force dictionary ID to specified value (default: random) \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
# ifndef ZSTD_NOBENCH
DISPLAY ( " \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " Benchmark arguments : \n " ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " -b# : benchmark file(s), using # compression level (default: %d) \n " , ZSTDCLI_CLEVEL_DEFAULT ) ;
2016-05-28 20:16:05 -07:00
DISPLAY ( " -e# : test all compression levels from -bX to # (default: 1) \n " ) ;
2018-01-24 04:59:44 -08:00
DISPLAY ( " -i# : minimum evaluation time in seconds (default: 3s) \n " ) ;
2016-05-28 20:16:05 -07:00
DISPLAY ( " -B# : cut file into independent blocks of size # (default: no block) \n " ) ;
2017-08-18 15:15:31 -07:00
DISPLAY ( " --priority=rt : set process priority to real-time \n " ) ;
2016-05-28 20:16:05 -07:00
# endif
return 0 ;
}
static int badusage ( const char * programName )
{
DISPLAYLEVEL ( 1 , " Incorrect parameters \n " ) ;
2017-03-23 11:13:52 -07:00
if ( g_displayLevel > = 2 ) usage ( programName ) ;
2016-05-28 20:16:05 -07:00
return 1 ;
}
static void waitEnter ( void )
{
int unused ;
DISPLAY ( " Press enter to continue... \n " ) ;
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 ) ] = = ' . ' ) ;
}
2016-06-03 06:14:09 -07:00
/*! readU32FromChar() :
2016-10-14 13:13:13 -07:00
@ return : unsigned integer value read from input in ` char ` format
allows and interprets K , KB , KiB , M , MB and MiB suffix .
2016-06-03 06:14:09 -07:00
Will also modify ` * stringPtr ` , advancing it to position where it stopped reading .
2016-10-14 13:13:13 -07:00
Note : function result can overflow if digit string > MAX_UINT */
2016-06-03 06:14:09 -07:00
static unsigned readU32FromChar ( const char * * stringPtr )
{
unsigned result = 0 ;
while ( ( * * stringPtr > = ' 0 ' ) & & ( * * stringPtr < = ' 9 ' ) )
result * = 10 , result + = * * stringPtr - ' 0 ' , ( * stringPtr ) + + ;
2016-10-17 17:48:48 -07:00
if ( ( * * stringPtr = = ' K ' ) | | ( * * stringPtr = = ' M ' ) ) {
result < < = 10 ;
if ( * * stringPtr = = ' M ' ) result < < = 10 ;
( * stringPtr ) + + ;
if ( * * stringPtr = = ' i ' ) ( * stringPtr ) + + ;
if ( * * stringPtr = = ' B ' ) ( * stringPtr ) + + ;
}
2016-06-03 06:14:09 -07:00
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 .
* @ return 0 and doesn ' t modify * stringPtr otherwise .
*/
2016-10-14 14:41:17 -07:00
static unsigned longCommandWArg ( const char * * stringPtr , const char * longCommand )
{
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
/**
* 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 ; }
2016-12-31 21:08:24 -08:00
return 0 ;
}
if ( stringPtr [ 0 ] ! = 0 ) return 0 ;
2017-05-01 23:40:20 -07:00
DISPLAYLEVEL ( 4 , " cover: k=%u \n d=%u \n steps=%u \n " , params - > k , params - > d , params - > steps ) ;
2016-12-31 21:08:24 -08:00
return 1 ;
}
2017-05-01 23:40:20 -07:00
/**
* parseLegacyParameters ( ) :
* reads legacy dictioanry builter parameters from * stringPtr ( e . g . " --train-legacy=selectivity=8 " ) into * selectivity
* @ 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 ;
return params ;
}
2016-12-31 21:08:24 -08:00
# endif
2017-01-30 13:07:24 -08:00
2016-12-13 03:18:07 -08:00
/** parseCompressionParameters() :
* reads compression parameters from * stringPtr ( e . g . " --zstd=wlog=23,clog=23,hlog=22,slog=6,slen=3,tlen=48,strat=6 " ) into * params
* @ 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 ; }
if ( longCommandWArg ( & stringPtr , " searchLength= " ) | | longCommandWArg ( & stringPtr , " slen= " ) ) { params - > searchLength = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
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 ; }
2017-09-05 21:11:18 -07:00
if ( longCommandWArg ( & stringPtr , " ldmHashLog= " ) | | longCommandWArg ( & stringPtr , " ldmhlog= " ) ) { g_ldmHashLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " ldmSearchLength= " ) | | longCommandWArg ( & stringPtr , " ldmslen= " ) ) { g_ldmMinMatch = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
2017-09-18 14:36:17 -07:00
if ( longCommandWArg ( & stringPtr , " ldmBucketSizeLog= " ) | | longCommandWArg ( & stringPtr , " ldmblog= " ) ) { g_ldmBucketSizeLog = readU32FromChar ( & stringPtr ) ; if ( stringPtr [ 0 ] = = ' , ' ) { stringPtr + + ; continue ; } else break ; }
if ( longCommandWArg ( & stringPtr , " ldmHashEveryLog= " ) | | longCommandWArg ( & stringPtr , " ldmhevery= " ) ) { g_ldmHashEveryLog = 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 ) ;
DISPLAYLEVEL ( 4 , " searchLength=%d, targetLength=%d, strategy=%d \n " , params - > searchLength , 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 )
{
DISPLAY ( WELCOME_MESSAGE ) ;
/* format support */
DISPLAYLEVEL ( 3 , " *** supports: zstd " ) ;
# if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>0) && (ZSTD_LEGACY_SUPPORT<8)
DISPLAYLEVEL ( 3 , " , zstd legacy v0.%d+ " , ZSTD_LEGACY_SUPPORT ) ;
# endif
# ifdef ZSTD_GZCOMPRESS
DISPLAYLEVEL ( 3 , " , gzip " ) ;
# endif
# ifdef ZSTD_LZ4COMPRESS
DISPLAYLEVEL ( 3 , " , lz4 " ) ;
# endif
# ifdef ZSTD_LZMACOMPRESS
DISPLAYLEVEL ( 3 , " , lzma, xz " ) ;
# endif
DISPLAYLEVEL ( 3 , " \n " ) ;
/* posix support */
# ifdef _POSIX_C_SOURCE
DISPLAYLEVEL ( 4 , " _POSIX_C_SOURCE defined: %ldL \n " , ( long ) _POSIX_C_SOURCE ) ;
# endif
# ifdef _POSIX_VERSION
DISPLAYLEVEL ( 4 , " _POSIX_VERSION defined: %ldL \n " , ( long ) _POSIX_VERSION ) ;
# endif
# ifdef PLATFORM_POSIX_VERSION
DISPLAYLEVEL ( 4 , " PLATFORM_POSIX_VERSION defined: %ldL \n " , ( long ) PLATFORM_POSIX_VERSION ) ;
# endif
}
2016-12-13 03:18:07 -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; }
2016-09-21 03:24:43 -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 ,
forceStdout = 0 ,
2018-02-09 15:53:27 -08:00
lastCommand = 0 ,
ldmFlag = 0 ,
2018-02-13 14:56:35 -08:00
main_pause = 0 ,
nbWorkers = 0 ,
nextArgumentIsOutFileName = 0 ,
nextArgumentIsMaxDict = 0 ,
nextArgumentIsDictID = 0 ,
nextArgumentsAreFiles = 0 ,
nextEntryIsDictionary = 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 ,
2018-02-09 15:53:27 -08:00
ultra = 0 ;
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 ;
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 ;
2016-07-27 06:09:11 -07:00
int cLevel = ZSTDCLI_CLEVEL_DEFAULT ;
int cLevelLast = 1 ;
2016-05-28 20:16:05 -07:00
unsigned recursive = 0 ;
2016-10-14 13:13:13 -07:00
unsigned memLimit = 0 ;
2016-05-28 20:16:05 -07:00
const char * * filenameTable = ( const char * * ) malloc ( argCount * sizeof ( const char * ) ) ; /* argCount >= 1 */
unsigned filenameIdx = 0 ;
const char * programName = argv [ 0 ] ;
const char * outFileName = NULL ;
const char * dictFileName = 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 ;
2016-07-27 06:09:11 -07:00
int dictCLevel = g_defaultDictCLevel ;
2016-05-28 20:16:05 -07:00
unsigned dictSelect = g_defaultSelectivityLevel ;
# ifdef UTIL_HAS_CREATEFILELIST
2016-09-21 03:24:43 -07:00
const char * * extendedFileList = NULL ;
2016-05-28 20:16:05 -07:00
char * fileNamesBuf = NULL ;
unsigned fileNamesNb ;
# endif
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 ( ) ;
2017-05-01 23:40:20 -07:00
int cover = 1 ;
2016-12-31 21:08:24 -08:00
# endif
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 */
2016-06-04 16:05:01 -07:00
( void ) recursive ; ( void ) cLevelLast ; /* not used when ZSTD_NOBENCH set */
2016-11-03 15:52:01 -07:00
( void ) dictCLevel ; ( void ) dictSelect ; ( void ) dictID ; ( void ) maxDictSize ; /* not used when ZSTD_NODICT set */
2017-09-01 10:19:38 -07:00
( void ) ultra ; ( void ) cLevel ; ( void ) ldmFlag ; /* not used when ZSTD_NOCOMPRESS set */
2016-11-03 15:52:01 -07:00
( void ) memLimit ; /* not used when ZSTD_NODECOMPRESS set */
2016-07-03 15:42:58 -07:00
if ( filenameTable = = NULL ) { DISPLAY ( " zstd: %s \n " , strerror ( errno ) ) ; exit ( 1 ) ; }
2016-05-28 20:16:05 -07:00
filenameTable [ 0 ] = stdinmark ;
2017-03-23 11:13:52 -07:00
g_displayOut = stderr ;
2017-03-24 17:06:09 -07:00
programName = lastNameFromPath ( programName ) ;
2018-02-13 14:56:35 -08:00
# ifdef ZSTD_MULTITHREAD
nbWorkers = 1 ;
# endif
2016-05-28 20:16:05 -07:00
/* preset behaviors */
2018-02-01 19:29:30 -08:00
if ( exeNameMatch ( programName , ZSTD_ZSTDMT ) ) nbWorkers = 0 ;
2017-03-24 17:06:09 -07:00
if ( exeNameMatch ( programName , ZSTD_UNZSTD ) ) operation = zom_decompress ;
2018-01-19 11:26:35 -08:00
if ( exeNameMatch ( programName , ZSTD_CAT ) ) { operation = zom_decompress ; forceStdout = 1 ; FIO_overwriteMode ( ) ; outFileName = stdoutmark ; g_displayLevel = 1 ; } /* supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_ZCAT ) ) { operation = zom_decompress ; forceStdout = 1 ; FIO_overwriteMode ( ) ; outFileName = stdoutmark ; g_displayLevel = 1 ; } /* behave like zcat, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_GZ ) ) { suffix = GZ_EXTENSION ; FIO_setCompressionType ( FIO_gzipCompression ) ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like gzip */
if ( exeNameMatch ( programName , ZSTD_GUNZIP ) ) { operation = zom_decompress ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like gunzip, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_GZCAT ) ) { operation = zom_decompress ; forceStdout = 1 ; FIO_overwriteMode ( ) ; outFileName = stdoutmark ; g_displayLevel = 1 ; } /* behave like gzcat, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_LZMA ) ) { suffix = LZMA_EXTENSION ; FIO_setCompressionType ( FIO_lzmaCompression ) ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like lzma */
if ( exeNameMatch ( programName , ZSTD_UNLZMA ) ) { operation = zom_decompress ; FIO_setCompressionType ( FIO_lzmaCompression ) ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like unlzma, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_XZ ) ) { suffix = XZ_EXTENSION ; FIO_setCompressionType ( FIO_xzCompression ) ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like xz */
if ( exeNameMatch ( programName , ZSTD_UNXZ ) ) { operation = zom_decompress ; FIO_setCompressionType ( FIO_xzCompression ) ; FIO_setRemoveSrcFile ( 1 ) ; } /* behave like unxz, also supports multiple formats */
if ( exeNameMatch ( programName , ZSTD_LZ4 ) ) { suffix = LZ4_EXTENSION ; FIO_setCompressionType ( FIO_lz4Compression ) ; } /* behave like lz4 */
if ( exeNameMatch ( programName , ZSTD_UNLZ4 ) ) { operation = zom_decompress ; FIO_setCompressionType ( 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
/* 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 ] ;
if ( ! argument ) continue ; /* Protection if argument empty */
2016-12-02 15:18:57 -08:00
if ( nextArgumentsAreFiles = = 0 ) {
/* "-" means stdin/stdout */
2016-07-04 09:16:16 -07:00
if ( ! strcmp ( argument , " - " ) ) {
if ( ! filenameIdx ) {
filenameIdx = 1 , filenameTable [ 0 ] = stdinmark ;
outFileName = stdoutmark ;
2017-03-23 11:13:52 -07:00
g_displayLevel - = ( g_displayLevel = = 2 ) ;
2016-07-04 09:16:16 -07:00
continue ;
} }
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Decode commands (note : aggregated commands are allowed) */
if ( argument [ 0 ] = = ' - ' ) {
2016-05-28 20:16:05 -07:00
2016-12-02 15:18:57 -08:00
if ( argument [ 1 ] = = ' - ' ) {
/* long commands (--long-word) */
if ( ! strcmp ( argument , " -- " ) ) { nextArgumentsAreFiles = 1 ; continue ; } /* only file names allowed from now on */
2017-06-15 15:07:54 -07:00
if ( ! strcmp ( argument , " --list " ) ) { operation = zom_list ; continue ; }
2016-12-02 15:18:57 -08:00
if ( ! strcmp ( argument , " --compress " ) ) { operation = zom_compress ; continue ; }
if ( ! strcmp ( argument , " --decompress " ) ) { operation = zom_decompress ; continue ; }
if ( ! strcmp ( argument , " --uncompress " ) ) { operation = zom_decompress ; continue ; }
2017-03-23 11:52:09 -07:00
if ( ! strcmp ( argument , " --force " ) ) { FIO_overwriteMode ( ) ; forceStdout = 1 ; followLinks = 1 ; continue ; }
2017-03-23 11:13:52 -07:00
if ( ! strcmp ( argument , " --version " ) ) { g_displayOut = stdout ; DISPLAY ( WELCOME_MESSAGE ) ; CLEAN_RETURN ( 0 ) ; }
if ( ! strcmp ( argument , " --help " ) ) { g_displayOut = stdout ; CLEAN_RETURN ( usage_advanced ( programName ) ) ; }
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 ; }
2016-12-02 15:18:57 -08:00
if ( ! strcmp ( argument , " --ultra " ) ) { ultra = 1 ; continue ; }
if ( ! strcmp ( argument , " --check " ) ) { FIO_setChecksumFlag ( 2 ) ; continue ; }
if ( ! strcmp ( argument , " --no-check " ) ) { FIO_setChecksumFlag ( 0 ) ; continue ; }
if ( ! strcmp ( argument , " --sparse " ) ) { FIO_setSparseWrite ( 2 ) ; continue ; }
if ( ! strcmp ( argument , " --no-sparse " ) ) { FIO_setSparseWrite ( 0 ) ; continue ; }
if ( ! strcmp ( argument , " --test " ) ) { operation = zom_test ; continue ; }
if ( ! strcmp ( argument , " --train " ) ) { operation = zom_train ; outFileName = g_defaultDictName ; continue ; }
2017-03-24 16:04:29 -07:00
if ( ! strcmp ( argument , " --maxdict " ) ) { nextArgumentIsMaxDict = 1 ; lastCommand = 1 ; continue ; } /* kept available for compatibility with old syntax ; will be removed one day */
if ( ! strcmp ( argument , " --dictID " ) ) { nextArgumentIsDictID = 1 ; lastCommand = 1 ; continue ; } /* kept available for compatibility with old syntax ; will be removed one day */
2016-12-02 15:18:57 -08:00
if ( ! strcmp ( argument , " --no-dictID " ) ) { FIO_setDictIDFlag ( 0 ) ; continue ; }
if ( ! strcmp ( argument , " --keep " ) ) { FIO_setRemoveSrcFile ( 0 ) ; continue ; }
if ( ! strcmp ( argument , " --rm " ) ) { FIO_setRemoveSrcFile ( 1 ) ; continue ; }
2017-02-07 11:12:59 -08:00
if ( ! strcmp ( argument , " --priority=rt " ) ) { setRealTimePrio = 1 ; continue ; }
2018-02-13 14:56:35 -08:00
if ( ! strcmp ( argument , " --single-thread " ) ) { nbWorkers = 0 ; singleThread = 1 ; continue ; }
2017-03-01 16:49:20 -08:00
# ifdef ZSTD_GZCOMPRESS
2017-02-14 00:47:29 -08:00
if ( ! strcmp ( argument , " --format=gzip " ) ) { suffix = GZ_EXTENSION ; FIO_setCompressionType ( FIO_gzipCompression ) ; continue ; }
2017-03-01 16:49:20 -08:00
# endif
2017-03-13 18:11:07 -07:00
# ifdef ZSTD_LZMACOMPRESS
if ( ! strcmp ( argument , " --format=lzma " ) ) { suffix = LZMA_EXTENSION ; FIO_setCompressionType ( FIO_lzmaCompression ) ; continue ; }
if ( ! strcmp ( argument , " --format=xz " ) ) { suffix = XZ_EXTENSION ; FIO_setCompressionType ( FIO_xzCompression ) ; continue ; }
# endif
2017-04-24 16:48:25 -07:00
# ifdef ZSTD_LZ4COMPRESS
if ( ! strcmp ( argument , " --format=lz4 " ) ) { suffix = LZ4_EXTENSION ; FIO_setCompressionType ( FIO_lz4Compression ) ; continue ; }
# endif
2016-12-02 15:18:57 -08:00
/* long commands with arguments */
2017-03-01 16:49:20 -08:00
# ifndef ZSTD_NODICT
2017-05-01 23:40:20 -07:00
if ( longCommandWArg ( & argument , " --train-cover " ) ) {
operation = zom_train ;
outFileName = g_defaultDictName ;
cover = 1 ;
2016-12-31 21:08:24 -08:00
/* Allow optional arguments following an = */
if ( * argument = = 0 ) { memset ( & coverParams , 0 , sizeof ( coverParams ) ) ; }
else if ( * argument + + ! = ' = ' ) { CLEAN_RETURN ( badusage ( programName ) ) ; }
else if ( ! parseCoverParameters ( argument , & coverParams ) ) { CLEAN_RETURN ( badusage ( programName ) ) ; }
continue ;
}
2017-05-01 23:40:20 -07:00
if ( longCommandWArg ( & argument , " --train-legacy " ) ) {
operation = zom_train ;
outFileName = g_defaultDictName ;
cover = 0 ;
/* Allow optional arguments following an = */
if ( * argument = = 0 ) { continue ; }
else if ( * argument + + ! = ' = ' ) { CLEAN_RETURN ( badusage ( programName ) ) ; }
else if ( ! parseLegacyParameters ( argument , & dictSelect ) ) { CLEAN_RETURN ( badusage ( programName ) ) ; }
continue ;
}
2016-12-31 21:08:24 -08:00
# endif
2018-02-01 19:29:30 -08:00
if ( longCommandWArg ( & argument , " --threads= " ) ) { nbWorkers = readU32FromChar ( & argument ) ; continue ; }
2016-12-02 15:18:57 -08:00
if ( longCommandWArg ( & argument , " --memlimit= " ) ) { memLimit = readU32FromChar ( & argument ) ; continue ; }
if ( longCommandWArg ( & argument , " --memory= " ) ) { memLimit = readU32FromChar ( & argument ) ; continue ; }
if ( longCommandWArg ( & argument , " --memlimit-decompress= " ) ) { memLimit = readU32FromChar ( & argument ) ; continue ; }
2017-01-30 11:17:26 -08:00
if ( longCommandWArg ( & argument , " --block-size= " ) ) { blockSize = readU32FromChar ( & argument ) ; continue ; }
2017-03-24 16:04:29 -07:00
if ( longCommandWArg ( & argument , " --maxdict= " ) ) { maxDictSize = readU32FromChar ( & argument ) ; continue ; }
if ( longCommandWArg ( & argument , " --dictID= " ) ) { dictID = readU32FromChar ( & argument ) ; continue ; }
2016-12-13 03:18:07 -08:00
if ( longCommandWArg ( & argument , " --zstd= " ) ) { if ( ! parseCompressionParameters ( argument , & compressionParams ) ) CLEAN_RETURN ( badusage ( programName ) ) ; continue ; }
2017-09-22 14:04:39 -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 */
CLEAN_RETURN ( badusage ( programName ) ) ;
}
/* Only set windowLog if not already set by --zstd */
if ( compressionParams . windowLog = = 0 )
compressionParams . windowLog = ldmWindowLog ;
continue ;
}
2016-12-02 15:18:57 -08:00
/* fall-through, will trigger bad_usage() later on */
}
argument + + ;
2016-07-04 09:16:16 -07:00
while ( argument [ 0 ] ! = 0 ) {
2016-09-21 05:20:56 -07:00
if ( lastCommand ) {
DISPLAY ( " error : command must be followed by argument \n " ) ;
2017-02-21 09:17:24 -08:00
CLEAN_RETURN ( 1 ) ;
2016-09-21 05:20:56 -07:00
}
2016-09-01 15:05:57 -07:00
# ifndef ZSTD_NOCOMPRESS
2016-07-04 09:16:16 -07:00
/* compression Level */
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
2016-08-12 09:04:15 -07:00
dictCLevel = cLevel = readU32FromChar ( & argument ) ;
2016-07-04 09:16:16 -07:00
continue ;
}
2016-09-01 15:05:57 -07:00
# endif
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
switch ( argument [ 0 ] )
{
/* Display help */
2017-08-19 13:33:50 -07:00
case ' V ' : g_displayOut = stdout ; printVersion ( ) ; CLEAN_RETURN ( 0 ) ; /* Version Only */
2016-07-04 09:16:16 -07:00
case ' H ' :
2017-03-23 11:13:52 -07:00
case ' h ' : g_displayOut = stdout ; CLEAN_RETURN ( usage_advanced ( programName ) ) ;
2016-05-28 20:16:05 -07:00
2016-10-28 13:58:31 -07:00
/* Compress */
case ' z ' : operation = zom_compress ; argument + + ; break ;
2016-07-04 09:16:16 -07:00
/* Decoding */
2016-12-06 17:56:20 -08:00
case ' d ' :
# ifndef ZSTD_NOBENCH
2018-03-05 13:50:07 -08:00
BMK_setDecodeOnlyMode ( 1 ) ;
if ( operation = = zom_bench ) { argument + + ; break ; } /* benchmark decode (hidden option) */
2016-12-06 17:56:20 -08:00
# endif
2016-12-06 16:49:23 -08:00
operation = zom_decompress ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Force stdout, even if stdout==console */
2016-08-12 09:04:15 -07:00
case ' c ' : forceStdout = 1 ; outFileName = stdoutmark ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Use file content as dictionary */
2016-09-21 05:20:56 -07:00
case ' D ' : nextEntryIsDictionary = 1 ; lastCommand = 1 ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Overwrite */
2017-03-23 11:52:09 -07:00
case ' f ' : FIO_overwriteMode ( ) ; forceStdout = 1 ; followLinks = 1 ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Verbose mode */
2017-03-23 11:13:52 -07:00
case ' v ' : g_displayLevel + + ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Quiet mode */
2017-03-23 11:13:52 -07:00
case ' q ' : g_displayLevel - - ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2017-05-02 15:40:42 -07:00
/* keep source file (default) */
2016-07-04 09:16:16 -07:00
case ' k ' : FIO_setRemoveSrcFile ( 0 ) ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Checksum */
2017-05-02 15:40:42 -07:00
case ' C ' : FIO_setChecksumFlag ( 2 ) ; argument + + ; break ;
2016-06-02 08:05:50 -07:00
2016-07-04 09:16:16 -07:00
/* test compressed file */
2016-10-28 13:58:31 -07:00
case ' t ' : operation = zom_test ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-07-13 05:15:08 -07:00
/* destination file name */
2016-09-21 05:20:56 -07:00
case ' o ' : nextArgumentIsOutFileName = 1 ; lastCommand = 1 ; argument + + ; break ;
2016-05-28 20:16:05 -07:00
2016-10-14 13:13:13 -07:00
/* limit decompression memory */
case ' M ' :
argument + + ;
memLimit = readU32FromChar ( & argument ) ;
break ;
2017-06-05 14:45:31 -07:00
case ' l ' : operation = zom_list ; argument + + ; break ;
2016-09-13 08:50:08 -07:00
# ifdef UTIL_HAS_CREATEFILELIST
2016-07-04 09:16:16 -07: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
2016-07-04 09:16:16 -07:00
/* Benchmark */
2017-01-19 16:59:56 -08:00
case ' b ' :
operation = zom_bench ;
argument + + ;
break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* range bench (benchmark only) */
case ' e ' :
2017-01-19 16:59:56 -08:00
/* compression Level */
argument + + ;
cLevelLast = readU32FromChar ( & argument ) ;
break ;
2016-07-04 09:16:16 -07:00
/* Modify Nb Iterations (benchmark only) */
case ' i ' :
2016-05-28 20:16:05 -07:00
argument + + ;
2017-01-19 16:59:56 -08:00
bench_nbSeconds = readU32FromChar ( & argument ) ;
2016-05-28 20:16:05 -07:00
break ;
2016-07-04 09:16:16 -07:00
/* cut input into blocks (benchmark only) */
case ' B ' :
argument + + ;
2017-01-19 16:59:56 -08:00
blockSize = readU32FromChar ( & argument ) ;
2016-07-04 09:16:16 -07:00
break ;
2017-01-01 17:05:45 -08:00
2017-11-17 00:22:55 -08:00
/* benchmark files separately (hidden option) */
case ' S ' :
argument + + ;
separateFiles = 1 ;
break ;
2017-01-19 16:59:56 -08:00
# endif /* ZSTD_NOBENCH */
2017-01-01 17:05:45 -08:00
/* nb of threads (hidden option) */
case ' T ' :
argument + + ;
2018-02-01 19:29:30 -08:00
nbWorkers = readU32FromChar ( & argument ) ;
2017-01-01 17:05:45 -08:00
break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07:00
/* Dictionary Selection level */
case ' s ' :
argument + + ;
dictSelect = readU32FromChar ( & argument ) ;
break ;
2016-05-28 20:16:05 -07:00
2016-07-04 09:16:16 -07: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
2016-07-04 09:16:16 -07:00
if ( ( * argument > = ' 0 ' ) & & ( * argument < = ' 9 ' ) ) {
BMK_setAdditionalParam ( readU32FromChar ( & argument ) ) ;
} else
2016-09-01 15:05:57 -07:00
# endif
2016-07-04 09:16:16 -07:00
main_pause = 1 ;
break ;
/* unknown command */
default : CLEAN_RETURN ( badusage ( programName ) ) ;
}
2016-05-28 20:16:05 -07:00
}
2016-07-04 09:16:16 -07:00
continue ;
} /* if (argument[0]=='-') */
2017-03-24 16:04:29 -07:00
if ( nextArgumentIsMaxDict ) { /* kept available for compatibility with old syntax ; will be removed one day */
2016-07-04 09:16:16 -07:00
nextArgumentIsMaxDict = 0 ;
2016-09-21 05:20:56 -07:00
lastCommand = 0 ;
2016-07-04 09:16:16 -07:00
maxDictSize = readU32FromChar ( & argument ) ;
continue ;
2016-05-28 20:16:05 -07:00
}
2016-07-04 09:16:16 -07:00
2017-03-24 16:04:29 -07:00
if ( nextArgumentIsDictID ) { /* kept available for compatibility with old syntax ; will be removed one day */
2016-07-04 09:16:16 -07:00
nextArgumentIsDictID = 0 ;
2016-09-21 05:20:56 -07:00
lastCommand = 0 ;
2016-07-04 09:16:16 -07:00
dictID = readU32FromChar ( & argument ) ;
continue ;
}
} /* if (nextArgumentIsAFile==0) */
2016-05-28 20:16:05 -07:00
if ( nextEntryIsDictionary ) {
nextEntryIsDictionary = 0 ;
2016-09-21 05:20:56 -07:00
lastCommand = 0 ;
2016-05-28 20:16:05 -07:00
dictFileName = argument ;
continue ;
}
if ( nextArgumentIsOutFileName ) {
nextArgumentIsOutFileName = 0 ;
2016-09-21 05:20:56 -07:00
lastCommand = 0 ;
2016-05-28 20:16:05 -07:00
outFileName = argument ;
if ( ! strcmp ( outFileName , " - " ) ) outFileName = stdoutmark ;
continue ;
}
/* add filename to list */
filenameTable [ filenameIdx + + ] = argument ;
}
2017-08-18 18:30:41 -07:00
if ( lastCommand ) { /* forgotten argument */
DISPLAY ( " error : command must be followed by argument \n " ) ;
CLEAN_RETURN ( 1 ) ;
}
2016-09-21 07:05:03 -07:00
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 */
nbWorkers = UTIL_countPhysicalCores ( ) ;
DISPLAYLEVEL ( 3 , " Note: %d physical core(s) detected \n " , nbWorkers ) ;
2017-04-13 12:28:28 -07:00
}
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 ;
2017-03-23 11:52:09 -07:00
if ( ! followLinks ) {
unsigned u ;
for ( u = 0 , fileNamesNb = 0 ; u < filenameIdx ; u + + ) {
if ( UTIL_isLink ( filenameTable [ u ] ) ) {
DISPLAYLEVEL ( 2 , " Warning : %s is a symbolic link, ignoring \n " , filenameTable [ u ] ) ;
} else {
filenameTable [ fileNamesNb + + ] = filenameTable [ u ] ;
}
}
filenameIdx = fileNamesNb ;
}
2016-05-28 20:16:05 -07:00
# ifdef UTIL_HAS_CREATEFILELIST
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 */
2017-03-23 11:52:09 -07:00
extendedFileList = UTIL_createFileList ( filenameTable , filenameIdx , & fileNamesBuf , & fileNamesNb , followLinks ) ;
2016-09-21 03:24:43 -07:00
if ( extendedFileList ) {
2016-08-01 05:26:49 -07:00
unsigned u ;
2016-09-21 03:24:43 -07:00
for ( u = 0 ; u < fileNamesNb ; u + + ) DISPLAYLEVEL ( 4 , " %u %s \n " , u , extendedFileList [ u ] ) ;
2016-05-28 20:16:05 -07:00
free ( ( void * ) filenameTable ) ;
2016-09-21 03:24:43 -07:00
filenameTable = extendedFileList ;
2016-05-28 20:16:05 -07:00
filenameIdx = fileNamesNb ;
}
}
# 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
2017-06-20 12:43:10 -07:00
int const ret = FIO_listMultipleFiles ( filenameIdx , filenameTable , g_displayLevel ) ;
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
2017-03-23 11:13:52 -07:00
BMK_setNotificationLevel ( g_displayLevel ) ;
2017-11-17 00:22:55 -08:00
BMK_setSeparateFiles ( separateFiles ) ;
2017-01-19 16:59:56 -08:00
BMK_setBlockSize ( blockSize ) ;
2018-02-01 19:29:30 -08:00
BMK_setNbWorkers ( nbWorkers ) ;
2017-11-17 00:02:37 -08:00
BMK_setRealTime ( setRealTimePrio ) ;
2017-01-19 16:59:56 -08:00
BMK_setNbSeconds ( bench_nbSeconds ) ;
2017-07-28 15:51:33 -07:00
BMK_setLdmFlag ( ldmFlag ) ;
2017-09-01 14:52:51 -07:00
BMK_setLdmMinMatch ( g_ldmMinMatch ) ;
BMK_setLdmHashLog ( g_ldmHashLog ) ;
2017-09-02 21:10:36 -07:00
if ( g_ldmBucketSizeLog ! = LDM_PARAM_DEFAULT ) {
BMK_setLdmBucketSizeLog ( g_ldmBucketSizeLog ) ;
}
if ( g_ldmHashEveryLog ! = LDM_PARAM_DEFAULT ) {
BMK_setLdmHashEveryLog ( g_ldmHashEveryLog ) ;
}
2017-11-17 00:02:37 -08:00
BMK_benchFiles ( filenameTable , filenameIdx , dictFileName , cLevel , cLevelLast , & compressionParams ) ;
2017-12-01 17:42:46 -08:00
# else
( void ) bench_nbSeconds ; ( void ) blockSize ; ( void ) setRealTimePrio ; ( void ) separateFiles ;
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 ;
zParams . notificationLevel = g_displayLevel ;
zParams . dictID = dictID ;
2016-12-31 21:08:24 -08:00
if ( cover ) {
2017-05-01 23:40:20 -07:00
int const optimize = ! coverParams . k | | ! coverParams . d ;
2018-02-01 19:29:30 -08:00
coverParams . nbThreads = nbWorkers ;
2017-06-26 21:07:14 -07:00
coverParams . zParams = zParams ;
2017-09-14 16:45:10 -07:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenameTable , filenameIdx , blockSize , NULL , & coverParams , 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 ;
2017-09-14 16:45:10 -07:00
operationResult = DiB_trainFromFiles ( outFileName , maxDictSize , filenameTable , filenameIdx , blockSize , & dictParams , NULL , 0 ) ;
2016-12-31 21:08:24 -08:00
}
2016-05-28 20:16:05 -07:00
# endif
goto _end ;
}
2017-07-18 14:45:49 -07:00
# ifndef ZSTD_NODECOMPRESS
if ( operation = = zom_test ) { outFileName = nulmark ; FIO_setRemoveSrcFile ( 0 ) ; } /* test mode */
# endif
2016-05-28 20:16:05 -07:00
/* No input filename ==> use stdin and stdout */
2016-08-25 16:43:47 -07:00
filenameIdx + = ! filenameIdx ; /* filenameTable[0] is stdin by default */
if ( ! strcmp ( filenameTable [ 0 ] , stdinmark ) & & ! outFileName ) 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 */
if ( ! strcmp ( filenameTable [ 0 ] , stdinmark ) & & IS_CONSOLE ( stdin ) ) CLEAN_RETURN ( badusage ( programName ) ) ;
2017-03-16 16:06:03 -07:00
if ( outFileName & & ! strcmp ( outFileName , stdoutmark ) & & IS_CONSOLE ( stdout ) & & ! strcmp ( filenameTable [ 0 ] , stdinmark ) & & ! forceStdout & & operation ! = zom_decompress )
2016-05-28 20:16:05 -07:00
CLEAN_RETURN ( badusage ( programName ) ) ;
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
2017-01-19 13:46:30 -08:00
/* No status message in pipe mode (stdin - stdout) or multi-files mode */
2017-03-23 11:13:52 -07:00
if ( ! strcmp ( filenameTable [ 0 ] , stdinmark ) & & outFileName & & ! strcmp ( outFileName , stdoutmark ) & & ( g_displayLevel = = 2 ) ) g_displayLevel = 1 ;
if ( ( filenameIdx > 1 ) & ( g_displayLevel = = 2 ) ) g_displayLevel = 1 ;
2016-05-28 20:16:05 -07:00
/* IO Stream/File */
2017-03-23 11:13:52 -07:00
FIO_setNotificationLevel ( g_displayLevel ) ;
2016-10-28 13:58:31 -07:00
if ( operation = = zom_compress ) {
2016-09-21 03:24:43 -07:00
# ifndef ZSTD_NOCOMPRESS
2018-02-01 19:29:30 -08:00
FIO_setNbWorkers ( nbWorkers ) ;
2017-01-24 17:02:26 -08:00
FIO_setBlockSize ( ( U32 ) blockSize ) ;
2017-07-28 15:51:33 -07:00
FIO_setLdmFlag ( ldmFlag ) ;
2017-09-01 14:52:51 -07:00
FIO_setLdmHashLog ( g_ldmHashLog ) ;
FIO_setLdmMinMatch ( g_ldmMinMatch ) ;
2017-09-02 21:10:36 -07:00
if ( g_ldmBucketSizeLog ! = LDM_PARAM_DEFAULT ) {
FIO_setLdmBucketSizeLog ( g_ldmBucketSizeLog ) ;
}
if ( g_ldmHashEveryLog ! = LDM_PARAM_DEFAULT ) {
2017-09-01 14:52:51 -07:00
FIO_setLdmHashEveryLog ( g_ldmHashEveryLog ) ;
}
2017-01-30 14:37:08 -08:00
if ( g_overlapLog ! = OVERLAP_LOG_DEFAULT ) FIO_setOverlapLog ( g_overlapLog ) ;
2016-09-21 07:46:08 -07:00
if ( ( filenameIdx = = 1 ) & & outFileName )
2016-12-13 04:24:59 -08:00
operationResult = FIO_compressFilename ( outFileName , filenameTable [ 0 ] , dictFileName , cLevel , & compressionParams ) ;
2016-05-28 20:16:05 -07:00
else
2017-12-12 18:32:50 -08:00
operationResult = FIO_compressMultipleFilenames ( filenameTable , filenameIdx , outFileName , suffix , dictFileName , cLevel , & compressionParams ) ;
2016-09-21 03:24:43 -07:00
# else
2017-08-19 01:23:49 -07:00
( void ) suffix ;
2016-09-21 03:24:43 -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
2017-09-22 14:04:39 -07:00
if ( memLimit = = 0 ) {
if ( compressionParams . windowLog = = 0 )
memLimit = ( U32 ) 1 < < g_defaultMaxWindowLog ;
else {
memLimit = ( U32 ) 1 < < ( compressionParams . windowLog & 31 ) ;
}
}
2016-10-14 13:13:13 -07:00
FIO_setMemLimit ( memLimit ) ;
2016-05-28 20:16:05 -07:00
if ( filenameIdx = = 1 & & outFileName )
operationResult = FIO_decompressFilename ( outFileName , filenameTable [ 0 ] , dictFileName ) ;
else
2017-12-12 18:32:50 -08:00
operationResult = FIO_decompressMultipleFilenames ( filenameTable , filenameIdx , outFileName , dictFileName ) ;
2016-05-28 20:16:05 -07:00
# else
DISPLAY ( " Decompression not supported \n " ) ;
# endif
}
_end :
if ( main_pause ) waitEnter ( ) ;
# ifdef UTIL_HAS_CREATEFILELIST
2016-09-21 03:24:43 -07:00
if ( extendedFileList )
UTIL_freeFileList ( extendedFileList , fileNamesBuf ) ;
2016-05-28 20:16:05 -07:00
else
# endif
free ( ( void * ) filenameTable ) ;
return operationResult ;
}